> Where you are: Part III, Chapter 20 of 40. Chapter 18 mined the browser; Chapter 19 reconstructed email, chat, and social-media activity from headers and databases. Now you turn to the files those channels carry — the photographs, videos, and...
In This Chapter
- The file you can see and the file you can't
- EXIF: the camera's testimony
- EXIF as evidence — and why you cannot trust it blindly
- Reading EXIF with ExifTool
- Document metadata: who, when, and how a document was made
- Detecting manipulation
- Steganography: hidden data and how to find it
- Video forensics
- Worked example: placing a photo in time and place
- Common mistakes
- Limitations: knowing when to stop
- Progressive project: analyze the photo and document evidence in your case
- Summary
Chapter 20: Photo, Video, and Document Forensics — Metadata, Manipulation Detection, and Content Analysis
Where you are: Part III, Chapter 20 of 40. Chapter 18 mined the browser; Chapter 19 reconstructed email, chat, and social-media activity from headers and databases. Now you turn to the files those channels carry — the photographs, videos, and documents themselves — and learn that every one of them is two files at once: the content a person sees, and the metadata almost nobody does. This is a home chapter for anchor case #4, the forensic image analyzed in court, where the question "when and where was this photograph taken, and by which device?" is answered not by the picture but by the bytes wrapped around it. We treat that case clinically throughout: procedure, law, and ethics only.
Learning paths: This is core territory for the 🔍 Forensic Examiner — EXIF, document metadata, and manipulation detection appear in nearly every case that involves a photo or a contested document. 📜 Legal/eDiscovery practitioners should read the document-metadata and PDF-incremental-update sections closely: authorship, revision history, "redactions" that did not redact, and editing-time anomalies decide more disputes than most lawyers realize. 🛡️ Incident Response meets data exfiltration hidden in images (steganography) and weaponized document metadata here. 💾 Data Recovery technicians get a genuine gift: the embedded thumbnail that survives when the full-resolution photo is gone, and the document author tag that re-identifies an orphaned, carved file.
The file you can see and the file you can't
Open a photograph and you see a moment. Open the file and you see a great deal more: the make and model of the camera that recorded the moment, the lens it wore, the exposure it chose, the exact second its shutter fired, sometimes the latitude and longitude where the photographer stood, the serial number of the camera body, the software that later touched the image, and — folded into a corner of the same file — a small, separate, often-forgotten second copy of the picture called the thumbnail. None of this is visible when you look at the image. All of it is sitting in plaintext or near-plaintext inside the file, waiting for anyone who knows where to look. The art of this chapter is learning to read the file, not just the photo.
The same is true of documents and video. A Word document is a sealed envelope with a return address, a postmark, an editing stopwatch, and frequently the names of everyone who touched it. A PDF that has been "redacted" with black rectangles may carry the redacted text, perfectly extractable, in the bytes beneath the boxes — and may carry three earlier drafts stacked invisibly inside it. A video file records, in a header most players never display, the moment it was created and the exact software library that encoded it. Behind each of these is a recurring truth of this book: every action leaves a trace, and the absence of a trace is itself a trace. A camera-original JPEG that contains no EXIF at all is not innocent; it is a JPEG that something stripped, and the stripping is a finding.
Consider the anchor case that runs through this chapter. A forensic image has been acquired and hashed under the discipline of Chapter 14 — Forensic Acquisition; it is a child-exploitation matter, and we will speak of it only at the level of procedure, law, and ethics — never content. Among the recovered files are photographs. The prosecution does not merely need to show that images existed on a device; it frequently needs to establish when an image was created, where, and on what device, because a defense may claim the files arrived by accident, were planted, or predate the defendant's control of the hardware. The metadata is where those questions are answered or honestly left open. A DateTimeOriginal of a particular evening, a GPS coordinate consistent with a known location, a camera serial number that matches a device seized from the suspect, a creation date that falls inside the window the defendant indisputably owned the phone — each is a brick in a wall the report must build carefully, and each comes with limits you are ethically required to state. We return to this case, clinically, in the worked example near the chapter's end, where the EXIF places a photo in time and place.
Why This Matters. Photos, videos, and documents are the content of most cases — the thing the dispute is actually about. The artifacts of Chapter 16 (registry, prefetch) prove a file was touched; the metadata in this chapter proves what the file is, when it was made, and whether it is what it claims to be. In a courtroom, "the suspect's account was logged in" is corroboration; "this photograph was taken by camera serial 042... on the evening of the 14th at these coordinates, and shows no sign of editing" can be the case. That power is exactly why the limitations section of this chapter matters as much as the techniques.
A map of the formats
Before the bytes, a map. Each media family stores metadata in a structure you must recognize on sight:
WHERE METADATA LIVES (this chapter)
┌────────────┬──────────────────────────────────────────────────────────────┐
│ FORMAT │ Container Metadata lives in │
├────────────┼──────────────────────────────────────────────────────────────┤
│ JPEG │ FF D8 … FF D9 segments APP1 (Exif TIFF block) + APP1 (XMP) │
│ PNG │ 89 50 4E 47 … chunks tEXt / iTXt / eXIf chunks │
│ HEIC/HEIF │ ISOBMFF boxes (like MP4) 'meta' box → 'Exif' item │
│ TIFF/RAW │ II*/MM* + IFDs IFD0 / ExifIFD / GPS IFD (native) │
├────────────┼──────────────────────────────────────────────────────────────┤
│ DOCX/XLSX │ ZIP (PK 03 04) docProps/core.xml + app.xml │
│ Legacy DOC │ OLE/CFB (D0 CF 11 E0) SummaryInformation streams │
│ PDF │ %PDF … %%EOF /Info dictionary + XMP metadata stream│
├────────────┼──────────────────────────────────────────────────────────────┤
│ MP4/MOV │ ISOBMFF atoms/boxes moov→mvhd/tkhd/mdhd creation_time │
│ AVI │ RIFF hdrl/strl + optional INFO list │
└────────────┴──────────────────────────────────────────────────────────────┘
Notice how much repeats. JPEG, TIFF, and camera RAW all share the same TIFF/EXIF block; HEIC and MP4 share the same ISOBMFF box structure; DOCX, XLSX, and PPTX are all just ZIP archives of XML. Learn the underlying structures once and the formats stop multiplying. That is the fourth theme in practice — technology changes, principles don't. The container of the future is not the container of 2010, but it will still be a header, an index, and a payload, and you will still parse it the same way.
EXIF: the camera's testimony
EXIF — Exchangeable Image File Format — is the metadata standard digital cameras and phones embed in JPEG, TIFF, and most RAW images. It is, in effect, the camera's contemporaneous notes on the photograph: what made it, how, when, and sometimes where. To read it with authority you must understand both the JPEG wrapper that carries it and the TIFF structure it is written in.
Inside a JPEG: the segment structure
A JPEG file is a sequence of segments, each introduced by a two-byte marker that always begins with 0xFF. The file opens with SOI (Start Of Image, FF D8) and closes with EOI (End Of Image, FF D9). Between them, application and table segments precede the compressed image data:
JPEG SEGMENT STRUCTURE
FF D8 SOI — Start Of Image (the JPEG signature)
FF E0 <len> "JFIF\0" ... APP0 — JFIF (density, units, tiny thumbnail)
FF E1 <len> "Exif\0\0" ... APP1 — EXIF (the TIFF block: camera, time, GPS)
FF E1 <len> "http://ns.adobe.com/xap/1.0/\0" ... APP1 — XMP (Adobe metadata)
FF ED <len> ... APP13 — Photoshop IRB / IPTC (captions, credits)
FF DB <len> ... DQT — Define Quantization Table(s)
FF C0 <len> ... SOF0 — Start Of Frame (baseline): dimensions, components
FF C4 <len> ... DHT — Define Huffman Table(s)
FF DA <len> ... SOS — Start Of Scan → compressed pixel data follows
... entropy-coded image data ...
FF D9 EOI — End Of Image
Two practical facts. First, every marker segment except SOI, EOI, and the raw scan data carries a two-byte big-endian length immediately after the marker, and that length includes the two length bytes themselves. Knowing this lets you walk the segments by hand in a hex viewer and lets a carver find the real end of a JPEG (the FF D9 after the scan) rather than guessing — see Chapter 7 — File Carving and the signature table in Appendix A. Second, anything after FF D9 is not part of the image. Decoders stop at EOI. Data appended past it is invisible to viewers and is one of the oldest tricks for hiding information inside an otherwise valid picture — we return to it under steganography.
The TIFF/EXIF block: byte order, IFDs, and tags
The EXIF payload inside the APP1 segment is not JPEG at all — it is a complete little TIFF file. After the marker, length, and the identifier "Exif\0\0" (hex 45 78 69 66 00 00), the TIFF block begins. Here is the head of a real EXIF JPEG:
Offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
00000000 FF D8 FF E1 2A 7C 45 78 69 66 00 00 49 49 2A 00 ....*|Exif..II*.
└SOI┘ └AP1┘ └len┘ └── "Exif\0\0" ──┘ └ TIFF hdr →
00000010 08 00 00 00 0A 00 0F 01 02 00 06 00 00 00 92 00 ................
└IFD0 off=8┘ │cnt=10│ └─────── IFD0 entry #1 ───────
Decode it left to right. FF D8 is SOI. FF E1 is APP1; 2A 7C is its big-endian length (0x2A7C = 10,876 bytes). "Exif\0\0" identifies the segment as EXIF. Then the TIFF header proper:
49 49is"II"— byte order is little-endian ("Intel"). The alternative is4D 4D("MM", "Motorola", big-endian). Every multi-byte value in this TIFF block is read in this order. Get the byte order wrong and every number you extract is garbage.2A 00is the TIFF magic number 42, written little-endian. (In anMMfile it would be00 2A.) Its job is to confirm the byte order you just read.08 00 00 00is a 4-byte offset to the first IFD (Image File Directory): offset 8. All offsets in the TIFF block are measured from the start of the TIFF header — theIIbyte — not from the start of the file. So IFD0 sits at file offset0x0C + 8 = 0x14.
An IFD is a list of tagged values. It starts with a 2-byte entry count (0A 00 = 10 entries here), followed by that many 12-byte entries, and ends with a 4-byte offset to the next IFD (or 00 00 00 00 if none). Each 12-byte entry has the same shape:
IFD ENTRY (12 bytes)
┌──────────┬──────────┬──────────────┬──────────────────────────┐
│ Tag (2) │ Type (2) │ Count (4) │ Value or Offset (4) │
├──────────┼──────────┼──────────────┼──────────────────────────┤
│ which │ data │ how many of │ the value itself if it │
│ field │ format │ that type │ fits in 4 bytes, else an │
│ │ │ │ offset to where it lives │
└──────────┴──────────┴──────────────┴──────────────────────────┘
Type codes: 1=BYTE 2=ASCII 3=SHORT(2B) 4=LONG(4B) 5=RATIONAL(2×LONG) 7=UNDEFINED 10=SRATIONAL
Read entry #1 above: tag 0F 01 (little-endian) = 0x010F = Make; type 02 00 = 2 (ASCII); count 06 00 00 00 = 6 characters; value/offset 92 00 00 00 = offset 0x92 (because 6 bytes do not fit in the 4-byte field, the entry stores a pointer; at TIFF offset 0x92 you would find "Canon\0"). That is the entire grammar of EXIF. Once you can parse one 12-byte entry, you can parse them all.
A JPEG's EXIF is organized into several IFDs chained and nested together:
EXIF IFD STRUCTURE
TIFF header (II/MM, 42, →IFD0)
│
├─ IFD0 (main image tags)
│ 0x010F Make 0x0110 Model 0x0131 Software 0x0132 ModifyDate
│ 0x8769 ExifIFDPointer ─────────────┐
│ 0x8825 GPSInfoIFDPointer ──────┐ │
│ (next-IFD offset) ─────────┐ │ │
│ │ │ │
├─ ExifIFD (the rich stuff) ◄────┼───┼────┘
│ 0x9003 DateTimeOriginal 0x9004 CreateDate (DateTimeDigitized)
│ 0x829A ExposureTime 0x829D FNumber 0x8827 ISO 0x920A FocalLength
│ 0xA431 BodySerialNumber 0xA434 LensModel 0xA435 LensSerialNumber
│ 0x927C MakerNote 0x9291 SubSecTimeOriginal 0x9000 ExifVersion
│ │
├─ GPS IFD ◄─────────────────────────┘ (via 0x8825)
│ 0x0001 LatitudeRef 0x0002 Latitude 0x0003 LongitudeRef 0x0004 Longitude
│ 0x0005 AltitudeRef 0x0006 Altitude 0x0007 GPSTimeStamp 0x001D GPSDateStamp
│
└─ IFD1 (the embedded THUMBNAIL) ◄── via IFD0's next-IFD offset
0x0201 ThumbnailOffset 0x0202 ThumbnailLength (+ its own small JPEG)
The timestamps that matter
EXIF carries several timestamps, and confusing them is a classic error. All are stored as ASCII strings in the format "YYYY:MM:DD HH:MM:SS" (note the colons in the date), and — crucially — the core three carry no timezone of their own:
DateTimeOriginal(0x9003) — when the photograph was taken: the moment the shutter fired. This is the timestamp you usually mean when you ask "when was this photo taken?"CreateDate/DateTimeDigitized(0x9004) — when the image was digitized. For a digital camera this equalsDateTimeOriginal; for a scanned film photo it is when it was scanned.ModifyDate(0x0132, the IFD0DateTime) — when the file was last modified. On a camera original it matches the other two; after editing in software it often does not, and a divergence is a flag.- Sub-second tags
SubSecTimeOriginal(0x9291) etc. add fractional seconds — useful for ordering burst shots and, as we will see, for spotting forgeries (a forger who sets the whole-second time rarely thinks to set sub-seconds). GPSDateStamp(0x001D) andGPSTimeStamp(0x0007) are written by the GPS receiver and are in UTC. Because the camera-clock timestamps are in local time with no zone recorded, the gap betweenDateTimeOriginal(local) andGPSDateStamp+GPSTimeStamp(UTC) is one of the few ways to recover the timezone the photo was taken in — a genuinely powerful corroboration when a location is in dispute.
Limitation. The camera-clock timestamps are only as accurate as the camera's clock. A clock never set after a battery pull may read the manufacturer's default (often
2000:01:01or the firmware build date); a clock left on home time during travel will disagree with the GPS UTC stamp by the travel offset; a clock set wrong is wrong forever in every photo it stamps. TreatDateTimeOriginalas "what the device believed the time was," and corroborate it — againstGPSDateStamp, against file-system MAC times (Chapter 21 — Timeline Analysis), against other photos in the same series — before you present it as the time.
GPS: the photo's place in the world
When location services are enabled, the GPS IFD records where the photo was taken. Coordinates are stored as three RATIONAL values — degrees, minutes, seconds — each a numerator/denominator pair, with a separate one-character reference giving the hemisphere. To turn that into the decimal degrees a map expects:
# EXIF GPS (degrees/minutes/seconds as rationals + N/S/E/W ref) -> decimal degrees.
# Illustrative reference code; exiftool/parsers do this for you.
def dms_to_decimal(dms, ref):
# dms = [(num,den), (num,den), (num,den)] for deg, min, sec
deg = dms[0][0] / dms[0][1]
minutes = dms[1][0] / dms[1][1]
seconds = dms[2][0] / dms[2][1]
dec = deg + minutes / 60 + seconds / 3600
if ref in ("S", "W"): # southern / western hemispheres are negative
dec = -dec
return round(dec, 6)
# Example values pulled from a GPS IFD:
lat = dms_to_decimal([(37,1), (48,1), (2997,100)], "N") # 37° 48' 29.97" N
lon = dms_to_decimal([(122,1), (25,1), (642,100)], "W") # 122° 25' 06.42" W
print(lat, lon) # -> 37.808325 -122.41845 (a waterfront in San Francisco)
That decimal pair drops onto any map. The GPS IFD often also holds GPSAltitude (with GPSAltitudeRef = 0 for above sea level, 1 for below), GPSImgDirection (the compass bearing the camera faced), and GPSDOP (a dilution-of-precision figure hinting at the fix quality). For investigations, GPS is the single most consequential EXIF field: it can place a device — and, by inference, a person — at a location at a time. It is also among the most misunderstood, and we treat its limits squarely later: it can be absent (location off), wrong (poor fix, assisted-GPS guess), stale (last-known location), or forged (written by software). Presence is a strong lead; presented as proof without corroboration, it has ended cross-examinations badly.
MakerNotes, serial numbers, and lens data
Beyond the standardized tags, the MakerNote (0x927C) is a manufacturer-private blob — Canon, Nikon, Sony, Apple, and others each pack proprietary data there. Modern parsers decode many of them, and the payload can be remarkable: the camera's body serial number (also exposed as the standardized BodySerialNumber, 0xA431), the lens serial number (0xA435), the shutter actuation count (how many photos the camera has ever taken — a near-unique fingerprint of a specific body at a moment in its life), internal temperature, firmware version, and the exact lens model. For attribution, a serial number is gold: if the BodySerialNumber in an image matches the serial engraved on a seized camera, you have bound that image to that physical device — subject, as always, to the caveat that metadata can be edited.
Recovery vs. Forensics. The embedded thumbnail (IFD1) is the clearest dual-use artifact in this chapter. For the 💾 recovery technician it is a lifeline: when the full-resolution image is corrupt, partially overwritten, or only its first sectors survive, the small JPEG in IFD1 — often complete in the first few kilobytes of the file — can be extracted intact, giving the client something of a lost photo (
exiftool -b -ThumbnailImage broken.jpg > thumb.jpg). For the 🔍 forensic examiner the very same thumbnail is an integrity check: many editors update the main image but forget to regenerate the thumbnail, so a thumbnail that differs from the visible picture — different crop, different content, an object the "final" image no longer shows — is direct evidence of manipulation. One small structure; one discipline reads it to restore, the other to expose.
EXIF as evidence — and why you cannot trust it blindly
EXIF is powerful precisely because it is detailed and contemporaneous. It is dangerous precisely because it is trivial to edit and trivial to remove. Both facts must live in your report at the same time.
On the evidentiary side: a consistent set of EXIF tags tells a coherent story. A Canon body serial matching a seized camera; a DateTimeOriginal whose sub-seconds and GPS-UTC offset are internally consistent; a Software tag that names the camera firmware rather than an editor; a thumbnail that matches the image; a quantization table characteristic of that camera model — when all of these agree, the conclusion that "this image is an unedited original from that device, taken then and there" is well-supported. This is the constructive use of EXIF in anchor case #4: establishing that a photograph was created on a device, in a window, at a place.
On the cautionary side, every one of those tags can be rewritten with a one-line command. exiftool -DateTimeOriginal="2019:06:01 12:00:00" photo.jpg changes the recorded capture time; exiftool -GPSLatitude=... -GPSLongitude=... invents a location; exiftool -all= photo.jpg strips the metadata entirely. Worse, ordinary, innocent handling destroys EXIF without anyone intending it: most social-media platforms strip EXIF on upload (Facebook, Instagram, Twitter/X re-encode and discard it — partly for user privacy), messaging apps often recompress images, and a "Save As" in many editors drops or rewrites tags. So the absence of EXIF tells you almost nothing about origin on its own — a photo with no EXIF may be a camera original that was posted to Instagram and downloaded again, not a forgery — while the presence of EXIF must be weighed for internal consistency before you trust it.
EXIF AS EVIDENCE — the two-handed finding
ON ONE HAND (supports authenticity) ON THE OTHER (demands caution)
• serial matches seized device • any tag editable with exiftool
• DateTimeOriginal ↔ GPS-UTC consistent • clock may be unset/wrong/zoned
• thumbnail matches the visible image • social media strips EXIF entirely
• Software = camera firmware, not editor • absence of EXIF ≠ forgery
• quantization table matches camera model • presence of EXIF ≠ authenticity
Legal Note. Because EXIF is editable, courts treat it as evidence to be authenticated and corroborated, not as self-proving truth. Under the Federal Rules of Evidence, the metadata is a statement about the file that the proponent must support — typically by tying it to other, harder-to-forge artifacts (file-system timestamps, carrier records, the device itself) and by an examiner who can explain both its meaning and its mutability. The frameworks for authentication, the Daubert/Frye standards your method must satisfy, and the duty to disclose the limits of your technique are developed in Chapter 25 — The Legal Framework and Chapter 27 — Expert Testimony. The one-sentence rule: present EXIF as what the file records, never as what indisputably happened.
Reading EXIF with ExifTool
The field-standard tool for metadata across photos, video, and documents is ExifTool (Phil Harvey's Perl program), which reads and writes more than a thousand tag sets across hundreds of formats. You run it against a working copy extracted from your verified image — never the original — and you record the copy's hash first (theme #2, the original is sacred). A first pass simply dumps everything:
# Hash the working copy before you touch it (chain of custody).
sha256sum ./work/IMG_0421.jpg >> coc.txt
# Dump ALL metadata, grouped by family, with both names shown.
exiftool -a -u -G1 ./work/IMG_0421.jpg
---- ExifIFD ----
[ExifIFD] Date/Time Original : 2024:03:14 21:07:42
[ExifIFD] Create Date : 2024:03:14 21:07:42
[ExifIFD] Sub Sec Time Original : 38
[ExifIFD] Exposure Time : 1/60
[ExifIFD] F Number : 1.8
[ExifIFD] ISO : 800
[ExifIFD] Focal Length : 5.1 mm
[ExifIFD] Lens Model : iPhone 13 back camera 5.1mm f/1.8
[ExifIFD] Body Serial Number : (decoded from MakerNote)
---- IFD0 ----
[IFD0] Make : Apple
[IFD0] Model : iPhone 13
[IFD0] Software : 17.3.1
[IFD0] Modify Date : 2024:03:14 21:07:42
---- GPS ----
[GPS] GPS Latitude Ref : North
[GPS] GPS Latitude : 37 deg 48' 29.97"
[GPS] GPS Longitude Ref : West
[GPS] GPS Longitude : 122 deg 25' 06.42"
[GPS] GPS Date Stamp : 2024:03:15
[GPS] GPS Time Stamp : 04:07:40
---- IFD1 ----
[IFD1] Thumbnail Offset : 1842
[IFD1] Thumbnail Length : 8364
Read what this single dump gives you. The device is an iPhone 13 running iOS 17.3.1; the photo was taken at 21:07:42 local on March 14; the GPS receiver, in UTC, says 04:07:40 on March 15. The seven-hour-and-change gap between local 21:07 and UTC 04:07 places the photographer in a UTC−7 zone (Pacific Daylight Time), which agrees with the San Francisco coordinates — the timestamps and the location corroborate each other. That internal consistency is exactly what strengthens an EXIF finding.
A few invocations earn their place in your muscle memory:
exiftool -time:all -a -G0:1 -s img.jpg # every timestamp, fully qualified
exiftool -gps:all -c "%+.6f" img.jpg # GPS as signed decimal degrees
exiftool -b -ThumbnailImage img.jpg > t.jpg # extract the embedded thumbnail
exiftool -htmlDump img.jpg > dump.html # annotated hex of every segment/IFD
exiftool -csv -r -DateTimeOriginal -GPSPosition -Model ./photos/ > index.csv
exiftool -validate -warning -a img.jpg # flag structural problems / tampering hints
The -htmlDump option is underused and superb: it renders the file as annotated hex, color-coding every marker, IFD, and tag, so you can see the structure this chapter described and confirm a parser's interpretation byte for byte — invaluable when a finding is contested. The -validate option reports structural anomalies (out-of-range offsets, duplicated IFDs, malformed values) that frequently accompany clumsy edits.
Tool Tip. Run ExifTool with
-api QuickTimeUTC=1on video so QuickTime/MP4 dates (stored as seconds since 1904, often without a zone) are interpreted in UTC consistently. And when you must demonstrate editability in court — to explain why you corroborated the EXIF rather than trusting it — do it on a copy of a copy, document the command, and keep the_originalbackup ExifTool writes automatically. Showing the judge thatDateTimeOriginalcan be changed in one command, on a throwaway file, is often the clearest way to make the limitation concrete. The full ExifTool reference lives in Appendix H — Command-Line Reference.Try This. On a practice image (see Appendix J — Practice Images and Lab Setup), pick a phone photo and run
exiftool -htmlDump. Find theFF E1/"Exif\0\0"/II*sequence with your own eyes. Then extract the thumbnail and compare it pixel for pixel with the full image. On a clean original they match; deliberately crop the main image in an editor, save, and look again — note whether the thumbnail updated. That single experiment teaches the thumbnail-mismatch tell better than any paragraph.
Document metadata: who, when, and how a document was made
Documents are, if anything, richer in metadata than photos, because they are produced by software that tracks authorship and editing for the user's own convenience — and never quite cleans up after itself. The three families you will meet are modern Office (OOXML), legacy binary Office (OLE/CFB), and PDF.
Office OOXML internals — it's a ZIP
A .docx, .xlsx, or .pptx is not a single binary blob; it is a ZIP archive of XML parts and media. Its signature is the ZIP local-file header 50 4B 03 04 (PK\x03\x04). Rename a .docx to .zip, open it, and you can read the whole document's structure as files:
report.docx (a ZIP — PK 03 04)
├── [Content_Types].xml
├── _rels/.rels
├── docProps/
│ ├── core.xml ← author, dates, revision, last-printed (Dublin Core)
│ ├── app.xml ← application, editing time, template, company, word count
│ └── custom.xml ← custom properties (often corporate document-management fields)
├── word/
│ ├── document.xml ← the actual text and tracked changes
│ ├── settings.xml ← rsids (revision save IDs), tracked-changes flag
│ ├── comments.xml ← reviewer comments (author + timestamp each)
│ └── media/ ← embedded images (each carrying ITS OWN EXIF!)
└── customXml/ ← bound external data
Two of these parts answer most authorship questions. docProps/core.xml holds the human metadata:
<cp:coreProperties xmlns:dc="http://purl.org/dc/elements/1.1/" ...>
<dc:creator>j.morales</dc:creator> <!-- ORIGINAL author -->
<cp:lastModifiedBy>IT-Admin</cp:lastModifiedBy> <!-- last person to save -->
<dcterms:created xsi:type="dcterms:W3CDTF">2024-03-10T14:22:00Z</dcterms:created>
<dcterms:modified xsi:type="dcterms:W3CDTF">2024-03-15T09:05:00Z</dcterms:modified>
<cp:revision>7</cp:revision> <!-- number of save cycles -->
<cp:lastPrinted>2024-03-12T10:00:00Z</cp:lastPrinted>
</cp:coreProperties>
The distinction between dc:creator (who created the document) and cp:lastModifiedBy (who last saved it) is often the whole game in an eDiscovery or fraud matter: a contract whose creator is a name nobody admits to, or whose lastModifiedBy postdates a claimed signing, breaks a story. docProps/app.xml adds the operational metadata: the Application and AppVersion that produced the file, the Company registered in the authoring Office install, the Template the document was based on (Normal.dotm, or a revealing corporate path), word/page/character counts, and — quietly devastating — TotalTime, the cumulative editing time in minutes. A "three-week project" whose TotalTime is 4 minutes was not what it claims to be; a document supposedly written by one person but bearing another's template path has a provenance problem.
Tracked changes, comments, and the revision trail
If track-changes was ever on, word/document.xml contains the edits inline as <w:ins> (insertions) and <w:del> (deletions), each stamped with w:author and w:date:
<w:ins w:author="j.morales" w:date="2024-03-11T16:40:00Z">
<w:r><w:t>the settlement amount is $250,000</w:t></w:r>
</w:ins>
<w:del w:author="r.chen" w:date="2024-03-14T11:02:00Z">
<w:r><w:delText>$180,000</w:delText></w:r>
</w:del>
Even when changes are accepted (which removes the w:ins/w:del markup), two residues persist: comments in comments.xml, each carrying an author and timestamp, and the rsid values ("revision save IDs") in settings.xml and throughout document.xml. Rsids are random tokens Word assigns per editing session and stamps onto the runs of text touched in that session; counting distinct rsids and mapping which text carries which rsid lets you reconstruct, in coarse outline, how many editing sessions a document went through and which passages were added together — a quiet, rarely-cleaned audit trail. Embedded images under word/media/ deserve their own pass: each is a real image file and carries its own EXIF, so a screenshot pasted into a memo can betray the capture time, the editing software, or even the GPS of a photo dropped into a report.
Legacy binary Office (OLE/CFB)
Pre-2007 .doc, .xls, and .ppt files use the OLE2 / Compound File Binary format, signature D0 CF 11 E0 A1 B1 1A E1 — a little FAT-like filesystem inside one file. Metadata lives in the \005SummaryInformation and \005DocumentSummaryInformation streams (author, last-saved-by, create/save times, total edit time, company, template). Legacy .doc is forensically notorious for two reasons: the "fast save" feature historically appended changes without rewriting the file, leaving deleted text recoverable in the binary; and the format stored a rolling list of the last ten authors and their save paths (\005SummaryInformation plus internal tables), so a single old document can name a chain of people and machines that touched it. When you meet legacy Office, exiftool reads the summary streams, and strings plus a structured parser (Apache Tika, olefile/oletools in Python) recovers more.
PDF metadata and incremental updates
A PDF is a text-structured file: header %PDF-1.7, a body of numbered objects (12 0 obj … endobj), a cross-reference (xref) table indexing where each object lives, and a trailer ending with %%EOF. Document metadata sits in two places that can disagree:
- the
/Infodictionary, referenced from the trailer:/Title,/Author,/Subject,/Keywords,/Creator(the app that authored the content),/Producer(the library that wrote the PDF), and dates in the formD:YYYYMMDDHHmmSS±HH'mm', e.g./CreationDate (D:20240315090500-05'00'); - an XMP metadata stream (a
/Type /Metadataobject holding RDF/XML), which newer tools write and which should mirror/Infobut often lags it after edits.
When /Info and XMP disagree — different authors, different dates, a /Producer that names an editor the document claims never to have seen — you have a manipulation signal. But the most important PDF concept for forensics is the incremental update. PDFs are designed to be modified by appending: a new body of changed objects, a new xref section, and a new trailer (with /Prev pointing back to the previous xref) are written after the existing %%EOF, leaving the original bytes in place. The consequences are large:
PDF WITH TWO INCREMENTAL UPDATES (one physical file)
%PDF-1.7
... original objects (revision 1) ...
xref ... ; trailer << /Root .. /Info .. >> ; %%EOF ← end of revision 1
... changed/added objects (revision 2) ...
xref ... ; trailer << /Prev .. >> ; %%EOF ← end of revision 2
... changed/added objects (revision 3) ...
xref ... ; trailer << /Prev .. >> ; %%EOF ← current revision
Count the %%EOF markers and you count the revisions. Earlier revisions — including text that a later revision "removed," form fields before they were filled, or content beneath a black "redaction" rectangle that was merely drawn over rather than deleted — frequently remain fully present and extractable in the earlier objects. This is the famous failure mode behind real-world leaks of "redacted" court filings and government documents: the box hides the text on screen, but the text is still in the byte stream, and pdftotext, mutool, qpdf --qdf, peepdf, or even strings will surface it. Theme #1, deleted ≠ destroyed, applies to documents exactly as it applies to disks: the visual removal of content is not the removal of the bytes.
exiftool -a -G1 contract.pdf # /Info + XMP, side by side (spot disagreement)
qpdf --show-npages --qdf contract.pdf out.pdf# normalize/expand: read every object as text
mutool clean -gggg contract.pdf flat.pdf # flatten incremental updates to inspect them
pdftotext -layout contract.pdf - # extract text — including under "redactions"
grep -a -c "%%EOF" contract.pdf # crude revision count
Recovery vs. Forensics. Document metadata serves both disciplines. For the 💾 recovery technician, a file carved from unallocated space (see Chapter 7 — File Carving) arrives with no name, no path, no parent folder — an orphan. Its internal metadata re-identifies it:
dc:creatornames the author,core.xmldates place it in time, and theCompany/Templateinapp.xmlties it to an organization, letting you return the right file to the right client. For the 🔍 forensic examiner, those same fields establish authorship, custody, and a revision history that a careful timeline can corroborate or contradict. The bytes are identical; one reads them to reunite a file with its owner, the other to prove who made it and when.
Detecting manipulation
"Is this image real?" is asked in cases from insurance fraud to harassment to the anchor matter, and it has no single push-button answer. What you have instead is a toolbox of independent tests, each of which produces a lead, and a discipline of corroboration. No single test proves a forgery; agreement among several, plus a plausible account of how the edit was made, is what supports a finding. Work from cheapest to most specialized.
Metadata inconsistencies — the first and cheapest pass
Before any pixel analysis, read the metadata against the claim. The cheap tells:
Software/Producernames an editor. A photo whoseSoftwaretag readsAdobe Photoshop 25.0is not a camera original, whatever it purports to be. (Absence of an editor tag does not prove the opposite — editors can be told to strip it.)- Thumbnail ≠ image. As covered above, an IFD1 thumbnail that differs from the visible picture is direct evidence the main image was changed after capture.
- Timestamp impossibilities.
ModifyDateearlier thanCreateDate;DateTimeOriginalafter the file-system creation time; aGPSDateStampinconsistent withDateTimeOriginalonce the timezone is reconciled. - Missing what should be present. A "phone photo" with no
Make/Model/lens data at all — possible if it traveled through social media, but suspicious if the chain of custody says it came straight off a camera. - Dimension/quantization mismatch. EXIF
PixelXDimensionthat disagrees with the actual decoded size, or a quantization table that matches a known editor rather than the claimed camera (next section).
Error Level Analysis (ELA)
Error Level Analysis exploits the fact that JPEG is lossy and that recompressing an already-compressed image introduces a predictable amount of additional error — unless a region has a different compression history than its surroundings. The procedure: resave the image at a known, uniform quality (say 90–95%), subtract it from the original, and amplify the difference. In an image compressed exactly once, the error level is roughly uniform across regions of similar texture. A region that was pasted in from another JPEG, or painted and saved separately, has been through a different number of compressions and stands out — brighter or differently textured — in the ELA result.
ELA — what you are actually computing
original.jpg ──► re-save at quality 95 ──► resaved.jpg
│
pixel-wise |original − resaved|, scaled up ─┴─► ELA image
uniform error → consistent compression history (likely untouched region)
bright patch → different history (possible paste / local edit) ← a LEAD, not proof
ELA is the workhorse of the free web service FotoForensics (by Neal Krawetz), and it is genuinely useful — and routinely overinterpreted. High-contrast edges, text overlaid on an image, and inherently sharp regions naturally show high error and are not evidence of tampering; a uniformly recompressed image (every region saved twice, e.g., after a social-media re-encode) can hide real edits by raising the floor everywhere; and a skilled forger can flatten ELA by recompressing the whole composite. ELA is a direction-finder: it tells you where to look more closely, not what you will conclude. Report it as such, never as "ELA proves this was edited."
JPEG quantization tables and double compression
Deeper in the JPEG lies stronger evidence. The DQT segment defines the quantization tables the encoder used, and these are a near-signature of the software: camera firmware, Photoshop's "Save for Web," GIMP, and phone pipelines each use characteristic tables and quality ladders. A JPEG whose quantization tables match Photoshop's known set, but whose EXIF claims a Canon original, is internally contradictory. More powerfully, double JPEG compression leaves statistical scars. When an image is decompressed, edited, and recompressed at a different quality, the DCT coefficient histograms develop periodic peaks and gaps — the "JPEG ghost" effect — because the coefficients were quantized twice on different grids. Detecting these requires examining the DCT coefficients directly (research tools and scripts, not a one-click button), but the principle is robust and harder to defeat than ELA: a singly-compressed camera original and a doubly-compressed edited file have measurably different coefficient statistics.
SINGLE vs DOUBLE JPEG COMPRESSION (DCT coefficient histogram, schematic)
single compression: ▁▂▃▅▇█▇▅▃▂▁ smooth, single-quantized
double compression: ▁▃▁▄▁▆▁█▁▆▁▄▁ periodic gaps/peaks (re-quantized)
└ regular comb pattern = a recompression fingerprint
Clone detection and splicing
Two more manipulation classes round out the toolbox. Copy-move (clone) forgery duplicates a region of the same image to cover or replicate something — to hide an object, or multiply a crowd. Because the cloned region is identical (or nearly so, after a feather) to its source, detectors find it by block matching (comparing overlapping image blocks for near-duplicates) or by keypoint matching (SIFT/SURF features that appear twice with the same descriptor). Splicing instead pastes content from another image; its tells are the seams — lighting and shadow directions that disagree, inconsistent noise floors (each camera/sensor imprints a characteristic noise pattern; a paste from another source carries the wrong noise), color-temperature mismatches, and edge discontinuities that ELA and noise analysis can surface. None of these is conclusive alone; a clone hit plus a noise discontinuity plus a metadata flag, with a coherent account of how the edit was produced, is what a defensible "this image was manipulated" finding looks like.
Why This Matters. Manipulation detection is the part of this chapter most likely to be wrong in the hands of an over-eager examiner, because the tools produce vivid, persuasive pictures (a glowing ELA map) that feel like proof. The professional posture is the fifth theme made concrete: each test is a hypothesis generator; conclusions require convergence across independent methods plus a plausible mechanism; and "the analysis is consistent with editing but does not establish it" is frequently the most honest finding available. The forthcoming AI-generated and deepfake media of Chapter 35 makes this humility more important, not less.
Steganography: hidden data and how to find it
Steganography hides the existence of a message, where encryption hides only its content. An image is a generous host: a photograph has millions of pixels, and altering the least significant bit of each changes the picture imperceptibly while carrying one bit of payload per channel per pixel. For the examiner and the incident responder, steganography matters as an exfiltration and concealment vector — data smuggled out of an organization inside an innocuous cat picture, or contraband payloads hidden in ordinary-looking media. Our treatment here is strictly detection (theme of defensive framing throughout this book); we do not teach embedding.
Where data hides
COMMON IMAGE DATA-HIDING TECHNIQUES (detection targets)
1. Appended data bytes after JPEG FF D9 (EOI) or after a PNG IEND chunk —
invisible to viewers, trivially carved back out
2. LSB embedding least-significant bit of pixel bytes (PNG/BMP especially) —
imperceptible visually; perturbs bit statistics
3. JPEG coefficient payload in DCT coefficients (JSteg, OutGuess, F5, JPHide)
4. Metadata stuffing payload in EXIF/XMP comment fields, PNG tEXt chunks
5. Palette / alpha ordering of a palette, or the alpha channel of a PNG
Detection
You rarely recover a stego payload blind (without the tool and key); you detect the likelihood that one is present and flag it. The pass, cheapest first:
file suspicious.png # is it really what the extension claims?
exiftool -a -u -G1 suspicious.png # oversized comment fields? odd tEXt chunks?
binwalk suspicious.jpg # embedded files / appended archives
xxd suspicious.jpg | tail # is there data AFTER FF D9 (EOI)?
zsteg -a suspicious.png # LSB / channel analysis for PNG & BMP
stegdetect suspicious.jpg # JSteg/JPHide/OutGuess signatures (JPEG)
steghide info suspicious.jpg # detect a steghide payload (needs passphrase to extract)
Beyond signatures, statistical analysis catches LSB embedding that has no tool signature. Natural images have correlated, non-uniform least-significant bits; LSB-replacement steganography flattens the distribution within "pairs of values" (2k and 2k+1 become equiprobable), which a chi-square test detects — the classic Westfeld–Pfitzmann attack — as does sample-pair analysis and the RS (regular/singular) method. Tools such as StegExpose automate several of these and score an image's likelihood of carrying an LSB payload. The cheapest and most reliable single check, though, remains the structural one: anything after a JPEG's FF D9 or a PNG's IEND is, by definition, not the image — carve it and identify it.
xxd output, tail of "vacation.jpg":
0004f3e0: ffd9 504b 0304 1400 0000 0800 a1b3 ... ......PK........
└EOI┘ └─ a ZIP (PK 03 04) appended AFTER end-of-image ─
The picture ends at FF D9; everything after is a hidden archive.
Ethics Note. Detection of a hidden payload often precedes examination of its contents, and the contents may be sensitive or contraband. Your authority to open what you find is governed by the warrant or engagement scope, and discovering certain material triggers mandatory legal duties — in the United States, the reporting obligation under 18 U.S.C. §2258A for child sexual abuse material. Do not improvise at the keyboard: stop, document, and follow the procedure. The full treatment of scope discipline, mandatory reporting, and examiner well-being (secondary trauma is real and must be managed) is owned by Chapter 28 — Ethics; the legal authority that defines what you may open is in Chapter 25.
Video forensics
Video raises the same questions as photos — when, where, what device, edited or not — over thousands of frames and inside more elaborate containers. The depth of video and deepfake analysis belongs to Chapter 35; here you learn the container metadata and the analytic vocabulary.
Container metadata: MP4/MOV atoms and AVI
The dominant container, MP4/MOV (and its relatives HEIC and the broader ISOBMFF family), is built from nested boxes (historically "atoms"), each a 4-byte big-endian size followed by a 4-byte type. The signature is the ftyp box at offset 4 (66 74 79 70), whose major brand distinguishes variants (isom, mp42, qt, heic). The metadata you want is in the moov box:
MP4 / MOV BOX TREE (metadata-bearing boxes marked ←)
ftyp major brand: mp42 / qt / heic ...
moov movie metadata container
├─ mvhd ← creation_time, modification_time, timescale, duration (movie header)
├─ trak one per track (video, audio, subtitle)
│ ├─ tkhd ← track creation/modification time, width, height
│ └─ mdia
│ ├─ mdhd ← media creation/modification time, language
│ └─ minf → stbl sample tables (stsd codec, stts timing, stsz sizes ...)
└─ udta → meta user data: ©day (date), make/model, GPS (©xyz on iPhone)
mdat the actual audio/video sample data
The creation_time and modification_time in mvhd, tkhd, and mdhd are seconds since midnight, January 1, 1904 UTC — the QuickTime epoch, which predates the Unix epoch by 2,082,844,800 seconds. Convert with that constant in mind:
import datetime
QT_EPOCH = datetime.datetime(1904, 1, 1, tzinfo=datetime.timezone.utc)
def qt_to_utc(seconds): # mvhd/tkhd/mdhd creation_time
return QT_EPOCH + datetime.timedelta(seconds=seconds)
# e.g. 3826889262 -> 2025-... (a real recording time, if the device clock was correct)
Apple devices additionally write a ©day date and a ©xyz GPS string into moov/udta/meta (ISO 6709 like +37.8083-122.4185/), so a phone video can carry both a creation time and a location — the same evidentiary value, and the same editability caveats, as photo EXIF. The older AVI container is a RIFF structure (signature 52 49 46 46, "RIFF", with form type "AVI "): the hdrl list holds the main header (avih) and per-stream headers (strh/strf) with frame rate, dimensions, and codec FourCC, and an optional INFO list can hold software and date strings.
MediaInfo
The standard cross-format inspector for audiovisual files is MediaInfo, which decodes container, codec, bitrate, resolution, frame rate, duration, and — forensically gold — the encoding application/library and any encoded date:
MediaInfo clip_evidence.mp4
General
Format : MPEG-4 (Base Media)
Codec ID : mp42 / isom
Duration : 00:00:18.420
Encoded date : UTC 2025-02-11 19:44:03
Writing application : Lavf61.7.100 ← FFmpeg's libavformat
Video
Format : AVC (H.264) Profile: High@L4.1
Frame rate : 29.970 (variable) ← VFR is itself a clue
Writing library : x264 core 164 ← a re-encoder, not a camera
Read that output the way you read EXIF. A clip whose Writing application is Lavf (libavformat) and whose Writing library is x264 was processed by FFmpeg — it is not a straight camera original; it has been transcoded, which is consistent with editing, format conversion, or messaging-app recompression, and demands the same two-handed caution as an edited photo. A device-original clip names the device's encoder; a variable frame rate where a constant one is expected, or an Encoded date that contradicts the file-system times, is a thread to pull.
Frame analysis and the road to deepfakes
Modern video codecs (H.264/H.265) compress by storing full I-frames (keyframes) periodically and encoding the frames between them as P/B-frames that describe only the changes, grouped into a GOP (Group Of Pictures). This structure matters forensically: an edit that splices or removes frames disturbs the GOP cadence, can produce a stray I-frame at a cut, and leaves recompression artifacts at the join; extracting and examining I-frames is the starting point for both authenticity analysis and for pulling the clearest still images from a clip. Surveillance and DVR systems complicate everything — many write proprietary container formats that standard players and even MediaInfo cannot fully parse, requiring the vendor's player or a specialized tool, and embedding their own (sometimes unreliable) timestamps that must be validated against the recorder's clock and an external time reference before you trust them. Frame-level authenticity — detecting synthetic faces, lip-sync mismatches, and generative artifacts — is the explicit subject of Chapter 35 — AI-Assisted Forensics and Deepfake Detection; this chapter hands you the container and frame vocabulary that chapter builds on.
Worked example: placing a photo in time and place
Return to anchor case #4 — the forensic image analyzed in court — at the level of procedure, law, and ethics only. The legal question put to you is narrow and consequential: a set of recovered photographs is alleged to be relevant to the matter; the defense contends the images could predate the defendant's possession of the device, or could have been placed there by another party. Your task is not to characterize the images. It is to determine, from metadata and corroborating artifacts, when each image was created, on what device, and — where recorded — where, and to state every conclusion with its limits. You work from a working copy whose hash you logged against the verified image.
You proceed file by file, exactly as the chapter taught:
1 — What device, and is the file an original? (EXIF IFD0 + MakerNote + thumbnail). exiftool -a -G1 on the first image reports Make: Apple, Model: iPhone 13, Software: 17.3.1, a decoded BodySerialNumber, and a LensModel consistent with that phone's camera. The IFD1 thumbnail, extracted with -b -ThumbnailImage, matches the full image — no post-capture re-crop. The Software tag names device firmware, not an editor. So far the file presents as a camera original from a specific iPhone model.
2 — When was it taken? (timestamps, reconciled). DateTimeOriginal reads 2024:03:14 21:07:42 (local, no zone). GPSDateStamp/GPSTimeStamp read 2024:03:15 04:07:40 UTC. The 7h offset places capture in UTC−7 (Pacific Daylight Time). SubSecTimeOriginal is populated (38), consistent with an unedited capture rather than a forger's round-second injection.
3 — Where was it taken? (GPS IFD). The GPS IFD yields 37.808325, −122.41845. You convert and record the decimal coordinates; you do not assert "the defendant was here" — you state that the device that wrote this file recorded these coordinates at this time, subject to GPS accuracy and to the editability of EXIF.
4 — Does the metadata corroborate or contradict the file system? You compare the EXIF capture time to the NTFS/APFS timestamps of the file as recovered, and to the device's own clock behavior across the photo set (the full discipline is Chapter 21 — Timeline Analysis). The file-creation time on the device's storage falls after DateTimeOriginal (a photo is created on disk at or after the shutter fires), and within the window the defendant indisputably possessed the device. Consistency across independent clocks is what elevates the EXIF time from "what the camera believed" toward "what the report can rely on."
5 — Any sign of editing or tampering? (the manipulation toolbox, applied with restraint). exiftool -validate reports no structural anomalies. The quantization tables are consistent with the iPhone pipeline, not a desktop editor. There is no Software editor tag, the thumbnail matches, and ModifyDate equals DateTimeOriginal. ELA on FotoForensics shows uniform error across like-textured regions, with bright response only at genuine high-contrast edges — no localized paste signature. You record that the analysis is consistent with an unedited original while noting that no single test can prove a negative.
6 — Bind the file to the seized device (the strongest available link). The decoded BodySerialNumber matches the serial of a phone seized from the defendant and documented in the chain of custody. You state the match — and you state, in the same breath, that serial numbers in EXIF are editable, that the match is corroborated by the device's clock pattern and by file-system times, and that the weight of the combined evidence, not any single field, supports the conclusion.
PHOTO METADATA FINDINGS — IMG_0421.jpg (anchor #4, clinical)
Field / test Value / result Weight & caveat
Make / Model Apple / iPhone 13 presents as device original
Body serial matches seized device STRONG, but EXIF is editable
DateTimeOriginal 2024-03-14 21:07:42 (local) camera clock; corroborate
GPS (UTC) date/time 2024-03-15 04:07:40 UTC ⇒ UTC−7 (PDT); zone recovered
GPS coordinates 37.808325, −122.41845 device-recorded; ±accuracy
Thumbnail (IFD1) matches full image no post-capture re-crop
Software tag 17.3.1 (firmware, not editor) no editor signature
exiftool -validate no anomalies structurally clean
ELA uniform; edges only consistent with unedited
File-system create after DateTimeOriginal, in independent clock agrees
possession window
Overall consistent with an unedited original from the seized device,
created 2024-03-14 ~21:07 PDT at the recorded coordinates —
each element corroborated; each stated with its limits.
Every line traces to an artifact in a hashed image; every conclusion carries its caveat; nowhere does the report characterize content or assert intent. That restraint is not timidity — it is what makes the finding survive cross-examination and what the sixth theme, the human cost is real, demands when your analysis bears on a person's liberty.
Chain of Custody. Treat every extracted artifact as evidence in its own right. When you pull a thumbnail, a
core.xml, or an MP4moovbox for closer analysis, you have created a derivative item: hash it, log its source ("ThumbnailImageextracted fromIMG_0421.jpg, SHA-256 …, from imageEX-07.E01, SHA-256 …"), and record the tool and version. The metadata you cite must be as traceable as the disk image it came from; the templates are in Appendix F — Chain of Custody and Report Templates, and the imaging discipline behind them is Chapter 14.War Story. A civil matter turned on a single photo a party swore was taken "the morning of the accident." The EXIF
DateTimeOriginalagreed with their story — to the minute. But theGPSTimeStamp(UTC) andDateTimeOriginal(local) implied a timezone seven hours off from where the photo was supposedly shot, theSubSecTimeOriginalwas an implausibly round00, and theSoftwaretag readAdobe Photoshop Lightroom. The picture had been exported through Lightroom with a hand-set capture time; the editor had changed the obvious field and never touched the GPS-UTC, the sub-seconds, or the producer tag. Three quiet fields, none of which the forger knew to align, unwound a sworn timeline. Every action leaves a trace — including the edit, and including the fields the editor forgot.
Common mistakes
- Trusting EXIF as if it were the camera's sworn oath. Every tag — time, GPS, serial, make — is editable in one command, and routine handling (social media, messaging) strips or rewrites it. Present EXIF as what the file records, corroborate the load-bearing fields, and state mutability in the report.
- Reading the absence of metadata as guilt (or innocence). A camera photo with no EXIF may simply have passed through Instagram; a document with no author may have been scrubbed or created by software that writes none. Absence is a question, not an answer.
- Confusing the EXIF timestamps.
DateTimeOriginal(taken),CreateDate(digitized), andModifyDate(last modified) are different fields with different meanings; the first is local-with-no-zone whileGPSDateStampis UTC. Citing the wrong one, or ignoring the zone gap, produces a confidently wrong time. - Overinterpreting ELA. Bright regions in an Error Level Analysis map mark high-contrast or differently-compressed areas, which include perfectly innocent edges and text. ELA points you where to look; it does not prove editing. Treating a glowing ELA image as a conviction is a credibility-ending error.
- Ignoring the embedded thumbnail and prior revisions. The IFD1 thumbnail can contradict the visible image; a PDF's incremental updates and a DOCX's rsids/comments can preserve content a later version "removed." Checking only the current, visible state misses the strongest evidence.
- Believing a black rectangle is a redaction. Drawing a box over PDF text does not delete the text;
pdftotext/mutool/stringsrecover it. Real redaction removes the bytes. Verify, never assume. - Forgetting that embedded images carry their own metadata. A screenshot or photo pasted into
word/media/brings its own EXIF — capture time, software, sometimes GPS — into the document. Examine the parts, not just the whole. - Working on the original. ELA requires resaving, ExifTool can write, and opening a file updates access times. Hash the working copy, operate on the copy, and keep the verified original untouched — theme #2 is not optional in a contested matter.
Limitations: knowing when to stop
The honest limits of this chapter are large, and a professional report states them as plainly as its findings. Metadata is mutable. EXIF, OOXML core properties, PDF /Info, and MP4 dates can all be altered without specialized skill; the most you can usually say from metadata alone is "the file records X," and the weight comes from corroboration across independent, harder-to-forge sources (file-system times, carrier or device logs, the physical device, multiple files in a series). When metadata is the only support for a contested time or place, say so and weight it accordingly.
Clocks lie. A camera or recorder timestamp is only as good as the device's clock, which may be unset, drifting, wrong, or on the wrong timezone. GPS is not certainty: it can be absent, imprecise (a poor fix or assisted-GPS estimate can be off by tens or hundreds of meters), stale (a last-known fix), or forged. A coordinate is "the location the device recorded," not "where the subject stood." Manipulation detection proves little in isolation. ELA, quantization analysis, double-compression statistics, and clone/splice detectors each generate leads; a defensible "this was manipulated" finding requires convergence across independent methods and a plausible account of how the edit was produced — and even then, "the analysis is consistent with editing but does not establish it" is frequently the most truthful conclusion. Proving an image is a genuine, untouched original is harder still: you can fail to find evidence of editing, but absence of evidence is not proof of authenticity.
Steganalysis detects likelihood, not contents. Statistical tests flag the probability of a hidden payload; without the embedding tool and key you usually cannot recover it, and you must not overclaim. Video is harder than photos on every axis — proprietary surveillance formats may resist parsing entirely, container timestamps may be unreliable, and synthetic media increasingly defeats naive authenticity checks (Chapter 35). And the hardest limit of all, the fifth theme made concrete: when an image came off social media stripped of EXIF, was recompressed by three apps, and exists only as a screenshot of a screenshot, the available metadata may simply be insufficient to determine origin, time, or authenticity — and "the evidence is insufficient to reach a conclusion" is a valid, professional finding. Forcing a conclusion the bytes will not support is how examiners are discredited.
Progressive project: analyze the photo and document evidence in your case
Continue building your Forensic Case File (the running deliverable from Chapter 5 — The Forensic Process, acquired in Chapters 14–15, and layered with artifacts since). This chapter you add the media-and-document metadata layer. Work only on hashed working copies extracted from your verified image; log each extraction in your chain-of-custody worksheet.
- Inventory and triage the media and documents. Recurse the image's user data with
exiftool -csv -r -DateTimeOriginal -CreateDate -GPSPosition -Make -Model -Software -Creator -Producerto build a single spreadsheet of every photo, video, and document with its key metadata. Sort by time and by device to surface clusters and outliers. - Pull the photo facts and reconcile the clocks. For the case-relevant images, record device (
Make/Model/serial), capture time (DateTimeOriginalwith sub-seconds), and — where present — GPS, converted to decimal degrees, with the local-vs-UTC offset reconciled to recover the timezone. Extract and compare each IFD1 thumbnail against its full image. - Pull the document facts and the hidden history. For each contested document, record
dc:creatorvscp:lastModifiedBy, created/modified dates,revision,TotalTime, andTemplatefrom OOXML (or the SummaryInformation streams of legacy.doc); for PDFs, compare/Infoagainst the XMP stream, count%%EOFmarkers, and check for text beneath "redactions" and for content in earlier incremental revisions. - Run a restrained manipulation pass. For images whose authenticity is in question, run
exiftool -validate, check theSoftware/quantization signature, and run ELA — recording each result as a lead with its caveat, never as proof. Note any image whose metadata, thumbnail, or compression history is internally inconsistent. - Add a media/document timeline and a findings table to the case file. Every entry sourced to an artifact (path + tool + extracted-item hash); every conclusion paired with its limitation (mutable metadata, clock reliability, GPS accuracy, manipulation-test caveat). You will merge this into the master timeline in Chapter 21 and fold it into the report in Chapter 26.
Save the CSV, the extracted thumbnails, the ELA outputs, and your findings table into the case-file folder. The capstone in Chapter 38 assembles the whole file; do not let this chapter's evidence live only in your head.
Summary
Every photo, video, and document is two files at once — the content a person sees and the metadata almost nobody does — and this chapter taught you to read the second one with authority and the discipline to state its limits. You learned the JPEG segment structure (FF D8 SOI through FF D9 EOI, with the EXIF carried in the APP1 segment) and the TIFF/EXIF block inside it: byte order (II/MM), the 42 magic, the chained and nested IFDs, and the 12-byte tag/type/count/value-or-offset entry that is the entire grammar of EXIF. You learned the tags that carry cases — Make, Model, Software, the body and lens serial numbers, the distinct timestamps (DateTimeOriginal local vs. GPSDateStamp/GPSTimeStamp in UTC, whose offset recovers the timezone), the GPS IFD's degrees-minutes-seconds rationals converted to decimal degrees, and the often-forgotten IFD1 thumbnail that both rescues a lost image and exposes a manipulated one. You learned that EXIF is powerful and trivially editable and routinely stripped, so its findings live with both hands on the table. You parsed document metadata — OOXML as a ZIP of XML with core.xml authorship and app.xml editing time, tracked changes and rsids and comments, legacy OLE/CFB summary streams, and PDF /Info versus XMP with the all-important incremental updates that preserve "redacted" and prior content (deleted ≠ destroyed, again). You built a restrained manipulation toolbox — metadata inconsistencies first, then ELA, quantization and double-compression statistics, clone and splice detection — and learned that each yields a lead, and that conclusions require convergence plus a plausible mechanism. You met steganography purely as a detection problem (appended data past FF D9, LSB statistics, chi-square, the structural carve), and the video container world (MP4/MOV ISOBMFF boxes with their 1904-epoch creation_time, AVI's RIFF, MediaInfo's encoder fingerprints, and the I-/P-/B-frame vocabulary that leads into deepfake detection). Finally you applied it all to anchor case #4, clinically: placing a photograph in time and place through reconciled timestamps, GPS, a serial match to a seized device, and a manipulation pass that found nothing — each element corroborated, each stated with its limits, none characterizing content or asserting intent. The formats will keep changing; the method will not — understand the structure, work the copy, parse with validated tools, corroborate across sources, and report every finding with its limitations intact.
You can now: - Parse a JPEG's segment structure and its embedded TIFF/EXIF block by hand, reading byte order, IFDs, and tag entries, and extract camera make/model, lens, serial, timestamps, and GPS with ExifTool. - Convert EXIF GPS to decimal degrees and reconcile local capture time against GPS-UTC to recover a timezone — while stating EXIF's editability and the limits of clock and GPS reliability. - Extract document metadata from OOXML (
core.xml/app.xml, tracked changes, rsids), legacy OLE/CFB, and PDF (/Infovs. XMP), and recover prior revisions and "redacted" text from PDF incremental updates. - Apply a restrained manipulation-detection toolbox — metadata inconsistencies, ELA, quantization/double-compression analysis, clone/splice detection — reporting each result as a corroborated lead, never as standalone proof. - Detect likely image steganography structurally and statistically (appended data, LSB/chi-square), and read video container metadata (MP4/MOV atoms, AVI, MediaInfo) including the 1904-epoch creation time. - Place a photograph in time, place, and device for a case file — corroborating across independent artifacts and stating every limitation — and add the media/document layer to your Forensic Case File.
What's next. Chapter 21 — Timeline Analysis — takes the timestamps you have been gathering everywhere (EXIF capture times, document created/modified dates, file-system MAC times, registry last-writes, event-log entries) and fuses them into a single, super-timeline with plaso/log2timeline, where you will learn to spot the contradictions — including timestomping — that reveal what really happened, and when.
Practice in exercises.md, test yourself with the quiz, apply it in the case studies, review the key takeaways, and go deeper with further reading.