Document Forensics: Extracting Evidence from Office & PDF Files
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
-
exiftool report.docxshowsLast Modified By: alice.martinandRevision: 23. The document was supposed to be draft 1. What questions does this raise? -
grep -c "%%EOF" contract.pdfreturns3. What does this mean? How do you access the content from revision 1? -
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.