Browse CTFs New CTF Sign in

Document Forensics: Extracting Evidence from Office & PDF Files

forensic_file_artifacts Difficulty 2–3 55 min certifiable

Theory

Prerequisites

  • DFA-K001: Forensic Principles
  • FND-K007: File Artefacts & Metadata (recommended)

Why This Lesson Matters

Documents are the most common vehicle for both malware delivery (weaponised Word macros, PDF exploits) and data exfiltration (confidential files emailed to a personal account). They are also rich forensic artefacts: every Office document records who created it, on what machine, when, through how many revisions, and even fragments of deleted content. This lesson teaches you to read a document as an investigator, not as a reader.


1. DOCX / Office Open XML Forensics

DOCX is a ZIP archive. This means all file forensics techniques — carving, metadata, archived content — apply directly.

# Verify it is a ZIP
file document.docx
# document.docx: Zip archive data

# List all internal files
unzip -l document.docx

# Extract all XML content
unzip -o document.docx -d /cases/IR-001/docx_unpacked/

# Key files inside:
# word/document.xml      → actual text content
# docProps/core.xml      → author, created, modified timestamps, revision count
# docProps/app.xml       → company name, manager, application version
# word/comments.xml      → comments (often contain reviewer names / internal notes)
# word/revisions/        → tracked changes (what was added/deleted per revision)

1.1 Core Metadata (docProps/core.xml)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties>
  <dc:creator>John Smith</dc:creator>               ← original author
  <cp:lastModifiedBy>Alice Martin</cp:lastModifiedBy>← last editor
  <cp:revision>7</cp:revision>                       ← number of saves
  <dcterms:created>2026-06-01T09:00:00Z</dcterms:created>
  <dcterms:modified>2026-06-08T14:32:17Z</dcterms:modified>
</cp:coreProperties>
# Quick extraction with exiftool
exiftool document.docx | grep -E "Author|Creator|Modifier|Revision|Created|Modified"

1.2 Revision History & Tracked Changes

Word's Track Changes feature records every edit with author name and timestamp. Even if the document was "accepted all changes" and distributed, revision data may remain in the XML.

cat /cases/IR-001/docx_unpacked/word/document.xml | 
  grep -oP '<w:ins[^>]+>.*?</w:ins>' | 
  python3 -c "import sys,re; [print(re.sub('<[^>]+>',',l)) for l in sys.stdin]"
# Outputs inserted text with author attribution

1.3 Hidden Content in DOCX

Hiding technique Where it lives How to find it
White text on white background word/document.xml — look for <w:color w:val="FFFFFF"/> grep for color tags, check surrounding text
Hidden text attribute <w:vanish/> tag wraps hidden text grep for <w:vanish
Comments word/comments.xml cat the file directly
Custom properties docProps/custom.xml may contain API keys, tokens, internal notes
# Find hidden text (vanish attribute)
grep -B2 -A5 "w:vanish" /cases/IR-001/docx_unpacked/word/document.xml

# Read all comments
cat /cases/IR-001/docx_unpacked/word/comments.xml | 
  python3 -c "import sys,re; print(re.sub('<[^>]+>',',sys.stdin.read()))"

2. PDF Forensics

PDFs are complex container formats with multiple layers where data can hide.

2.1 PDF Structure

A PDF is a sequence of objects (dictionaries, streams, arrays) with a cross-reference table at the end.

%PDF-1.7                    ← header with version
1 0 obj                     ← object 1: document catalog
<</Type /Catalog /Pages 2 0 R>>
endobj

...                         ← many objects

xref                        ← cross-reference table
0 15
0000000000 65535 f          ← first entry (always free)
0000000009 00000 n          ← byte offset of object 1

%%EOF                       ← end of file marker

Incremental updates: A PDF can have multiple %%EOF markers — each represents one save/revision. Content hidden in an earlier revision may not be visible in the current version but is still present in the file.

# Count revisions
grep -c "%%EOF" document.pdf

# Extract revision 1 (bytes before first %%EOF)
awk '/%%EOF/{exit} {print}' document.pdf > revision1.pdf

2.2 PDF Metadata

# Extract all metadata
exiftool document.pdf | grep -E "Author|Creator|Producer|Created|Modified|Keywords|Subject"

# pdfinfo (poppler-utils)
pdfinfo document.pdf

# Key fields for forensics:
# Author: who created it
# Creator: what application (e.g., "Microsoft Word 2019")
# Producer: what generated the PDF (e.g., "Adobe Acrobat Distiller")
# CreationDate: when the original document was created
# ModDate: when the PDF was last modified

2.3 Hidden Content in PDFs

# Extract all text layers (including white-on-white text)
pdftotext -layout document.pdf -     # may reveal hidden text

# Strings in the raw PDF (catches data in comments and stream headers)
strings document.pdf | grep -iE "flag|ctf|secret|token|key|password"

# Check for embedded files
pdf-parser.py --stats document.pdf   # statistics
pdf-parser.py --search /EmbeddedFile document.pdf   # find embedded files

# Extract JavaScript (often malicious in weaponised PDFs)
pdf-parser.py --search /JS document.pdf
pdf-parser.py --search /JavaScript document.pdf

2.4 PDF Comment Streams

PDF allows arbitrary comment lines (starting with %). Data can be hidden in comments after the %%EOF or within comment lines in the body.

grep "^%" document.pdf | grep -v "^%PDF|^%%EOF"   # non-standard comments
xxd document.pdf | tail -20   # check bytes after last %%EOF

3. Spreadsheet (XLSX) Forensics

XLSX is also a ZIP archive with the same metadata structure as DOCX.

unzip -l spreadsheet.xlsx
# xl/worksheets/sheet1.xml → cell data
# xl/sharedStrings.xml     → all string values across the workbook
# xl/styles.xml            → formatting (white font = possible hidden content)
# docProps/core.xml        → author, revision count

# Find white-on-white cells
grep -B5 "FFFFFF" xl/styles.xml | grep -E "fontId|xfId"
# Then correlate style IDs with cell references in sheet1.xml

# Find very-hidden sheets (wsState="veryHidden")
grep "veryHidden" xl/workbook.xml

4. Common Mistakes

Mistake 1: Reading a PDF and concluding it contains no hidden content. PDFs can have white text, hidden layers, incremental revisions, embedded files, and JavaScript. Opening it in a viewer shows only the visible layer. Always use pdftotext, strings, and pdf-parser.

Mistake 2: Trusting the "Author" field. The Author field is set by the application from the registered user name and can be changed by anyone. It is corroborating evidence, not proof of authorship.

Mistake 3: Skipping custom properties in DOCX. docProps/custom.xml is rarely mentioned but often contains interesting data: internal tracking fields, API keys embedded by careless developers, and sometimes flags in CTF challenges.


5. Practice Exercises

  1. exiftool report.docx shows Last Modified By: alice.martin and Revision: 23. The document was supposed to be draft 1. What questions does this raise?

  2. grep -c "%%EOF" contract.pdf returns 3. What does this mean? How do you access the content from revision 1?

  3. You find a DOCX with <w:color w:val="FFFFFF">secret_api_key_here</w:color> in the XML. The document looks blank. Explain what this is and how it would be missed by a casual reviewer.


6. Lab

Assessment mode: flag

challenge_spec_id: 355 — PDF metadata forensics

You are given a document.pdf.

Task: 1. Run exiftool to check metadata fields 2. Run strings and pdftotext to check for hidden text 3. The flag is hidden in one of the metadata fields or PDF comment streams


7. Framework Alignment

Framework Role Competency Confidence
CCSSF-DFA Digital Forensics Analyst Document artefact forensics High
CCSSF-CIR Cyber Incident Responder Malicious document investigation High
NICE 2.2.0 Digital Forensics (INV-FOR-002) K0133 — Document forensics High

8. Further Reading

  • pdf-parser.py (Didier Stevens) — https://blog.didierstevens.com — The essential PDF forensics tool
  • DOCX format specification (ECMA-376) — The authoritative reference for Open XML
  • "Learning PDF Forensics" — Magnet Forensics blog — Practical walkthrough

Learning Objectives

["Unzip a DOCX file and extract the author, last modified by, revision count, and creation timestamp from docProps/core.xml using exiftool and direct XML inspection", "Use pdftotext, strings, and grep to identify hidden text in a PDF, and detect whether the PDF has multiple revisions by counting %%EOF markers", "Identify white-on-white hidden text in a DOCX by finding FFFFFF color tags in the document XML and locate the corresponding text content"]

Lesson Outline

Prerequisites → Why this matters → DOCX/Open XML structure (ZIP, key files) → Core metadata extraction → Revision history and tracked changes → Hidden content in DOCX (white text, vanish, comments, custom properties) → PDF structure (objects, xref, incremental updates) → PDF metadata (exiftool, pdfinfo) → Hidden content in PDFs (text layers, comments, embedded files, JavaScript) → XLSX forensics → Common mistakes → Practice exercises → Lab (flag, spec 355) → Framework alignment → Further reading

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.