> Where you are: Part III, Chapter 19 of 40. Chapter 16 taught you to read what Windows recorded about a user's activity; Chapter 17 did the same for macOS and Linux; Chapter 18 reconstructed where they went on the web. Now you read what they said —...
In This Chapter
- Why communications are the richest — and most scattered — evidence you will handle
- Email I: the file formats you must recognize
- Email II: header analysis — tracing a message to its origin
- Email III: webmail recovery from the browser
- Chat applications: one technique unlocks most of them
- Social media: what is local versus what requires legal process
- Metadata in communications: the data about the data
- Tool demonstration: an email-and-chat pass
- Worked example: the engineer's email trail
- Common mistakes
- Limitations: knowing when to stop
- Progressive project: recover the communication evidence (email and chat) for the case
- Summary
Chapter 19: Email, Chat, and Social Media Forensics — Recovering Communication Evidence
Where you are: Part III, Chapter 19 of 40. Chapter 16 taught you to read what Windows recorded about a user's activity; Chapter 17 did the same for macOS and Linux; Chapter 18 reconstructed where they went on the web. Now you read what they said — and to whom. Communications are where intent, relationships, and the words "send it to my personal account" actually live, which makes this chapter the place where anchor case #2, the departing engineer, finally produces a confession in the suspect's own writing, and where anchor case #4, the child-exploitation matter, meets the legal machinery for compelling records from a provider. This is also the chapter where one technical skill — recovering deleted records from SQLite — quietly unlocks half of modern chat forensics.
Learning paths: This chapter is essential for the 🔍 Forensic Examiner (email and chat are the substance of nearly every insider, harassment, fraud, and exploitation case) and for 📜 Legal/eDiscovery practitioners, who must know exactly which legal instrument compels which class of records — get that wrong and the evidence is suppressed. 🛡️ Incident Response lives in the email-header and webmail sections (business email compromise and phishing start here). 💾 Data Recovery technicians get a genuinely practical payoff: recovering a corrupt PST, an orphaned OST, or a deleted WhatsApp thread for a grieving family is bread-and-butter recovery work, and the SQLite recovery technique transfers to dozens of applications.
Why communications are the richest — and most scattered — evidence you will handle
Open almost any consequential investigation and you will find that the decisive evidence is something a person wrote to another person. A spreadsheet proves a number; an email proves a decision. A document proves a file existed; a chat thread proves who knew what, and when, and how they felt about it. Communications carry intent in a way that no system artifact can, which is exactly why they are fought over so hard in court and why you must handle them with unusual care for both their technical recovery and their legal admissibility.
They are also the most scattered evidence you will ever chase. A single conversation can exist simultaneously in five places, each governed by different rules and recoverable by different techniques. Consider the anchor case for this chapter — the senior mechanical engineer from Chapter 16 who copied turbine-housing CAD files to a personal SanDisk before resigning. The USB story you built from the registry is damning, but counsel wants more: did the engineer also send the designs out by email? The answer, it turns out, lives in pieces. There is an Outlook OST file on the workstation, the cached copy of the corporate mailbox, holding sent items the engineer thought they had deleted. There are browser artifacts (Chapter 18) showing a personal Gmail session opened on a corporate machine — including an IndexedDB cache fragment of a "compose" window with an attachment name. There is the corporate mail gateway's journaled copy. And there is whatever sits on Google's servers, reachable only with the right legal instrument. Same conversation; five locations; five different methods to get it.
WHERE COMMUNICATION EVIDENCE LIVES (the spectrum you must learn to navigate)
ON THE DEVICE IN THE CLOUD (provider's servers)
┌──────────────────────────┐ ┌────────────────────────────────┐
│ Outlook PST / OST │ │ Gmail / Outlook.com / Yahoo │
│ Thunderbird MBOX, EML/MSG │ ─sync/───▶ │ mailbox content │
│ App SQLite DBs │ cache │ WhatsApp/Signal: little/none* │
│ WhatsApp msgstore.db │ │ Telegram cloud chats │
│ Signal signal.db │ ◀───pull │ Slack/Discord/Teams messages │
│ Telegram cache4.db │ on open │ Facebook/Instagram/X content │
│ Browser cache/IndexedDB │ │ │
│ (webmail, Electron apps)│ │ ── REQUIRES LEGAL PROCESS ── │
└──────────────────────────┘ │ preservation · subpoena · │
YOU recover this directly │ 2703(d) order · search warrant │
from a forensic image └────────────────────────────────┘
* Signal stores almost nothing
recoverable server-side by design
The skill this chapter builds is reading that whole spectrum: pulling what is on the device with recovery and forensic technique, recognizing what only the provider holds, and knowing precisely which legal instrument compels it. Get the technique right and you recover deleted messages nobody believed survived. Get the legal step wrong and a court throws all of it out. Both halves matter, and this chapter teaches both.
Why This Matters. Across corporate investigations, family-law matters, criminal cases, and incident response, the single most-litigated category of digital evidence is communications. Juries understand a chat thread far more readily than a hex dump of a hive. But communications are also the most privacy-laden data you will ever touch — they implicate the people your custodian talked to, who are not parties to your investigation. The technical recovery is only half the job; doing it within legal authority and ethical scope is the other half, and it is the half that ends careers when it goes wrong.
Email I: the file formats you must recognize
Email forensics begins with format literacy. Before you can analyze a message you must know what container it is in, how that container stores deleted items, and whether it is encrypted. Four families cover almost everything you will meet: Outlook's PST/OST, the Unix-lineage MBOX, the single-message EML/EMLX, and Outlook's single-message MSG.
PST and OST — Outlook's databases
The PST (Personal Storage Table) and OST (Offline Storage Table) are Microsoft's on-disk mailbox databases. A PST is a self-contained mail archive a user creates ("Archive.pst", "Personal Folders"); an OST is the cached copy of a server mailbox (Exchange or Microsoft 365) that Outlook keeps locally so it can work offline. They share a binary format documented in Microsoft's open [MS-PST] specification, which means you can parse them with open tools rather than guessing.
Both begin with the same four magic bytes, 21 42 44 4E — the ASCII string !BDN — followed by a partial CRC and the client signature SM (53 4D). The version word at offset 0x0A tells you which dialect you are holding:
PST/OST HEADER (MS-PST)
Offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
00000000 21 42 44 4E E1 9A 7C 4F 53 4D 17 00 19 00 01 01 !BDN..|OSM......
└─ "!BDN" ─┘ └ CRC ────┘ └"SM"┘ └wVer┘ └Ver┘ └pl┘
│
wVer = 0x0017 = 23 → UNICODE PST/OST (Outlook 2003 and later; large files)
wVer = 14 or 15 → ANSI PST (Outlook 97–2002; 2 GB hard limit)
wVer = 36/37 → extended/"large" OST format (newer Outlook)
The ANSI versus Unicode distinction is not academic. ANSI PSTs (the 2 GB format) corrupt the moment they cross 2 GB, and a huge share of "my Outlook won't open" recovery jobs are ANSI PSTs that quietly hit the ceiling. Knowing the format from the header tells you immediately whether you are looking at a size-limit corruption (recover with scanpst.exe or a PST repair tool, or carve the readable nodes) or something else.
Internally the format is layered, and you do not need to parse it by hand, but understanding the layers tells you what survives deletion:
PST/OST INTERNAL LAYERS (MS-PST)
┌───────────────────────────────────────────────────────────────────┐
│ MESSAGING layer folders, messages, attachments, recipients │
│ (the things a human sees) as MAPI properties │
├───────────────────────────────────────────────────────────────────┤
│ LTP layer Lists, Tables, Properties — Property Context (PC) │
│ and Table Context (TC) that hold those properties │
├───────────────────────────────────────────────────────────────────┤
│ NDB layer Node Database — the b-trees that index everything │
│ NBT (Node BTree) + BBT (Block BTree) + free map │
└───────────────────────────────────────────────────────────────────┘
Three forensic facts fall out of this structure. First, the "password." A PST can have a password, but it does not encrypt the data — Outlook merely stores a CRC32 of the password in the header and checks it before opening. Any forensic PST tool ignores it entirely; the password is a speed bump, not a lock. Second, the on-disk "encryption." The NDB layer offers three bCryptMethod modes (at offset 0x0201 in a Unicode file): 0x00 = none, 0x01 = permute (a fixed byte-substitution table — "compressible encryption," trivially reversed), 0x02 = cyclic (a rolling XOR keyed by block ID). Neither is cryptography in any meaningful sense; both are obfuscation that every parser undoes automatically. Do not let a vendor's "PST encryption" claim make you think you need a key. Third, deletion. When a user deletes a message, Outlook unlinks its node from the folder's Table Context, but the message's blocks linger in the PST's free space — tracked by the free map but not yet reused — until the PST is compacted. That is the chapter's first encounter with the foundational theme: deleted is not destroyed. Until the store is compacted, soft-deleted and even hard-deleted (Shift+Delete) items are routinely recoverable.
Recovery vs. Forensics. The same orphaned PST serves both trades. A 💾 recovery technician whose client says "Outlook lost ten years of email" runs a PST repair pass, fixes the b-tree, and hands back a working store — speed and restoration are the goal. A 🔍 examiner never touches the original PST: they hash it, work a copy, and use a read-only parser (
libpff, below) that extracts every message including the free-space remnants, because the deleted items are often the entire point. One artifact, two postures — repair-in-place versus extract-and-preserve.
MBOX, EML, EMLX, and MSG
Outside the Outlook world, email is plain-text or single-message containers, and you should recognize each on sight:
- MBOX — the classic Unix mailbox: every message concatenated into one text file, each one introduced by a line that begins, at column zero, with
From(the word "From" followed by a space, called the "From_" line) plus the sender and a timestamp. Thunderbird, Apple Mail's internal stores, Evolution, and — importantly — Google Takeout all produce MBOX. When a custodian exports their Gmail, you receive MBOX, so this format shows up constantly in eDiscovery. - EML — a single message saved verbatim in RFC 5322 (formerly 2822/822) format: headers, a blank line, then the MIME body. An EML usually begins with a header line such as
Return-Path:,Received:,From:, orDelivered-To:. This is the lingua franca; almost everything can export to EML. - EMLX — Apple Mail's on-disk single-message format: a byte-count line, then the RFC 5322 message, then an Apple property-list (plist) trailer carrying flags and metadata. Found under
~/Library/Mail/(see Chapter 17 — macOS and Linux Forensics). - MSG — Outlook's single-message file. It is an OLE Compound File (the same Microsoft CFB container as Office documents and the Jump Lists from Chapter 16), so it starts with the signature
D0 CF 11 E0 A1 B1 1A E1. Inside, MAPI properties live in streams named__substg1.0_<PROPTAG>— for example__substg1.0_0C1F001Fis the sender's SMTP address,0037001Fis the subject. Tools read these streams directly.
MBOX structure — the "From_" separator is the record delimiter
From MAILER-DAEMON Fri Mar 15 18:59:02 2024 ← message 1 starts (col 0)
Return-Path: <jrivera@corp-victim.com>
Received: from ...
Subject: Turbine housing — final
...body...
From jrivera@corp-victim.com Fri Mar 15 19:07:44 2024 ← message 2 starts (col 0)
...
Limitation. The MBOX "From_" line is a convention, not a fielded structure, and a body line that happens to begin "From the desk of…" can be mistaken for a separator by a naive parser (this is the classic "From-munging" problem). Robust parsers require the separator to be followed by a plausible address and date, but corrupt or hand-edited MBOX files can still split wrong. When message counts matter, verify with two tools.
Recovering deleted and corrupt email
Recovery breaks into three situations. Corrupt but present: a PST/OST that won't open is repaired with scanpst.exe, a commercial repair tool, or by carving its internal nodes; an MBOX truncated mid-file still yields every complete message before the truncation. Deleted messages inside a healthy store: the free-space remnants in a PST/OST are extracted by a forensic parser that walks the NDB free map rather than just the live folder tree. The whole file deleted from disk: you fall back to file carving (the discipline of Chapter 7 — File Carving) — search unallocated space for the !BDN PST header or for RFC 5322 patterns (\nReceived:, \nMessage-ID:) and EML/MBOX fragments. Signatures for all of these live in Appendix A — File Signatures Reference.
The open-source workhorse for Outlook stores is Joachim Metz's libpff:
# Inspect a store: format (ANSI/Unicode), encryption mode, message counts.
pffinfo Archive.pst
# Recover EVERYTHING — live folders AND recoverable deleted items — to a tree of files.
# -m all : extract all item types -q : quiet
# -f text : also emit a text rendering -t : target directory
pffexport -m all -q -t ./pst_out Archive.pst
# ./pst_out/recovered/ ← items pffexport rebuilt from the store's free space
The recovered/ subtree pffexport produces is exactly the "deleted is not destroyed" payoff: messages the user emptied from Deleted Items, sitting in the PST's free pages, reassembled. For an OST specifically, remember its special value: because it is a cached copy, an OST frequently contains messages that have since been deleted from the server mailbox — an OST is a time capsule of the mailbox as of the last sync. An orphaned OST (one whose Outlook profile or account is gone) is still fully parseable with libpff; you do not need the original account to read it.
Tool Tip. For MBOX and EML at scale,
readpstconverts a PST to MBOX, and Python's standardmailboxand
Email II: header analysis — tracing a message to its origin
The body of an email is what a person wrote. The headers are what the machines recorded as it traveled, and they are far harder to forge convincingly. Header analysis answers the questions that decide phishing, business-email-compromise, harassment, and spoofing cases: where did this message really come from, and is the sender who they claim to be?
The Received chain — read it from the bottom up
Every mail server (MTA) that handles a message prepends a Received: header to the top of the message. The consequence is the single most important rule in email forensics: the topmost Received: header is the last hop (nearest the recipient); the bottommost is the first hop (nearest the origin). To trace a message to its source, read the Received: chain from the bottom up.
Each Received: header follows an RFC 5321 pattern: from <name the sender claimed> (<reverse-DNS of the connecting IP> [<actual connecting IP>]) by <our receiving server> with <protocol> id <queue-id>; <timestamp>. The crucial datum is the bracketed IP — the actual TCP peer the receiving server saw — because that is observed, not claimed.
ANNOTATED HEADERS — a spoofed "PayPal" phish captured in the corporate mailbox
(read the Received: chain BOTTOM-UP)
Return-Path: <billing@paypa1-secure.com> ← envelope sender (RFC5321.MailFrom)
Received: from mx.corp-victim.com (mx.corp-victim.com [203.0.113.10])
by store.corp-victim.com with LMTP id 8a2f
for <ap@corp-victim.com>; Tue, 12 Mar 2024 09:41:55 -0400 ← (3) our internal hop [TRUSTED]
Received: from smtp-out.cheaphost.example (smtp-out.cheaphost.example [198.51.100.77])
by mx.corp-victim.com (Postfix) with ESMTPS id 4b9c
for <ap@corp-victim.com>; Tue, 12 Mar 2024 09:41:54 -0400 ← (2) OUR EDGE MX [TRUST BOUNDARY]
Received: from [10.0.0.5] (unknown [185.220.101.42])
by smtp-out.cheaphost.example with ESMTPA id 2f1a;
Tue, 12 Mar 2024 13:41:50 +0000 ← (1) origin claim [NOT trusted]
Authentication-Results: mx.corp-victim.com;
spf=fail (sender IP 198.51.100.77 not permitted) smtp.mailfrom=paypa1-secure.com;
dkim=none;
dmarc=fail (p=reject) header.from=paypal.com
Message-ID: <a7f3e9c1-3b22-4e8e-9f10-2024@paypa1-secure.com>
From: "PayPal Security" <service@paypal.com> ← DISPLAY name + domain the victim SEES
Date: Tue, 12 Mar 2024 09:41:48 -0400
Subject: Your account access has been limited
X-Mailer: PHPMailer 6.8.0 (https://github.com/PHPMailer/PHPMailer)
Work it bottom-up. Hop (1) is the claimed origin written by a server you do not control, so trust it only as far as you trust smtp-out.cheaphost.example — but it records a connecting IP of 185.220.101.42, an address in a range widely published as Tor exit nodes, which is itself a finding. Hop (2) is your own edge MX, mx.corp-victim.com, and the header it wrote is trustworthy: the message genuinely arrived at your perimeter from 198.51.100.77. Everything at or above your trust boundary is reliable; everything below it is only as honest as the foreign relays that wrote it. This trust-boundary concept is the whole game — an attacker can fabricate Received: headers, but only below the first server you actually control. The X-Mailer: PHPMailer line, finally, betrays a bulk-mail script rather than a genuine PayPal MTA.
SPF, DKIM, and DMARC — the authentication triangle
Three DNS-based mechanisms let a receiver test whether mail claiming to be from a domain is authorized. Their results are recorded in the Authentication-Results header (and legacy Received-SPF), which is written by the receiving server — so on a message you pulled from the recipient's mailbox, the verdict has already been computed for you.
- SPF (Sender Policy Framework) — the domain publishes a DNS
TXTrecord listing IPs allowed to send for it, e.g.v=spf1 include:_spf.google.com ~all. The receiver checks whether the connecting IP is on the list. Results:pass,fail(hardfail,-all),softfail(~all),neutral,none. Critical limitation: SPF validates the envelope sender (RFC5321.MailFrom/Return-Path), not the visibleFrom:header. A message can pass SPF and still display a forgedFrom:. - DKIM (DomainKeys Identified Mail) — the sending domain cryptographically signs selected headers and the body; the signature rides in a
DKIM-Signature:header carrying the signing domaind=, the selectors=, the list of signed headersh=, the body hashbh=, and the signatureb=. The receiver fetches the public key from<selector>._domainkey.<d>in DNS and verifies. Apassmeans those headers and the body have not been altered since this domain signed them — strong evidence of both integrity and domain authenticity. - DMARC (Domain-based Message Authentication, Reporting & Conformance) — published at
_dmarc.<domain>(v=DMARC1; p=reject; rua=mailto:...). DMARC ties the previous two to the visibleFrom:by requiring alignment: SPF or DKIM must pass and its domain must match theFrom:domain. The policyp=tells receivers what to do on failure:none(monitor),quarantine(spam folder), orreject.
In the phish above, SPF failed (the sending IP is not authorized for the lookalike paypa1-secure.com), DKIM was absent, and DMARC failed against the real paypal.com with a published policy of p=reject. The story the headers tell — Tor-range origin, unauthorized relay, no cryptographic signature, a one-character lookalike domain (paypa**1**), and a display-name spoof — is a textbook fraudulent email, and every element is documented in headers that are far harder to fake than the friendly From: a victim sees.
Legal Note. Header timestamps are a minefield of time zones. Each hop stamps its own clock with its own UTC offset (note the phish jumps from
-0400to+0000between hops). Before you build any timeline, normalize every timestamp to UTC and say so in your report, and treat a server with an obviously wrong clock as a known error source rather than silently "correcting" it. Timeline normalization is the subject of Chapter 21 — Timeline Analysis. A header that is internally inconsistent — aDate:that precedes the earliestReceived:, or a downstream hop time-stamped before an upstream hop — is itself evidence of tampering or a broken relay, and you flag it, you do not paper over it.
Message-ID, X-headers, and spoofing tells
The Message-ID: is a globally unique identifier assigned at composition, formatted <unique-token@domain>. Its domain often reveals the true originating system even when From: is forged, and it is the key you use to correlate the same message across the sender's Sent items, the recipient's Inbox, and the mail gateway's journal — three copies of one message that should share a Message-ID. The X-Originating-IP: header (added by some webmail providers) can hand you the client IP directly; X-Mailer:/User-Agent: name the composing software; and a careful read for display-name spoofing ("PayPal" <attacker@evil.com>), lookalike/homoglyph domains, and reply-to mismatches (Reply-To: pointing somewhere other than From:) catches the social-engineering layer the protocols alone miss.
Email III: webmail recovery from the browser
When the custodian used Gmail, Outlook.com, Yahoo, or Proton through a browser, there is no PST or OST — the mailbox lives on the provider's servers (which means it is governed by the legal-process rules later in this chapter). What remains on the device is whatever the browser cached, and recovering it is an application of Chapter 18 — Browser and Internet Forensics. It is worth recapping what specifically betrays webmail use:
- History and typed URLs — visits to
mail.google.com,outlook.live.com,mail.proton.me; the registry'sTypedURLs(Chapter 16) catching a hand-typed webmail address; search-bar terms. - Cache — Chromium's cache (the
Cache_Data/block files or Simple-Cachef_*/<hash>_0entries) can hold rendered message fragments, inline images, and attachment thumbnails. Cached JSON API responses sometimes contain message snippets and subject lines. - Offline stores — Gmail's offline mode writes a substantial IndexedDB (LevelDB) store at
...\User Data\Default\IndexedDB\https_mail.google.com_0.indexeddb.leveldb\, which can contain entire message bodies, contact lists, and labels available with no network at all. Outlook-on-the-web and others use Service Worker caches and IndexedDB similarly. - Autofill and downloads — the email address itself in autofill data; saved attachments in the Downloads database and on disk.
WEBMAIL FOOTPRINT on a Chromium profile (recover per Chapter 18)
...\User Data\Default\
History ← mail.google.com visits, search terms
Cache\Cache_Data\ ← message HTML fragments, attachment thumbnails
IndexedDB\https_mail.google.com_0.indexeddb.leveldb\ ← OFFLINE Gmail: full bodies
Service Worker\CacheStorage\ ← cached app shell + API responses
Network\Cookies ← session cookies (auth state, last-active hints)
Recovery vs. Forensics. For 💾 recovery, webmail cache is sometimes the only copy of a message a user swears they "lost" after a provider purge — carving Gmail's IndexedDB can hand a client back correspondence the provider no longer retains. For 🔍 forensics, the same cache proves local access — that this machine, this profile, viewed this message at this time — which is independent of, and complementary to, whatever you later obtain from the provider by warrant. The cache shows access on the endpoint; the warrant return shows the authoritative server content. You want both, and you must not confuse one for the other.
Chat applications: one technique unlocks most of them
Modern chat lives overwhelmingly in SQLite databases on the device. WhatsApp, Signal, Telegram, iMessage, Skype, Viber, Android SMS/MMS, and many others all store messages in SQLite. Learn to recover deleted records from SQLite once and you can apply it to all of them — so we build that skill first, then walk the major apps and what is and is not encrypted.
The SQLite substrate — and why deleted messages survive
A SQLite database is a single file beginning with the 16-byte magic string SQLite format 3\000 (53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00). The two bytes at offset 16 give the page size (big-endian), and the file is a sequence of fixed-size pages holding b-tree nodes whose cells contain the actual rows.
SQLITE HEADER (first 32 bytes)
Offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
00000000 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 SQLite format 3.
00000010 10 00 01 01 00 40 20 20 ... .....@
└ page size 0x1000 = 4096 └ write/read fmt, reserved...
Here is the forensic gift. When SQLite "deletes" a row, it does not erase the bytes. It marks the cell's space as a free block within the page (chained on the page's freeblock list) or releases the whole page to the database freelist. The old row data remains in place until that space is reused by a later insert — and is erased outright only by an explicit VACUUM. So deleted messages persist in three places: as free blocks inside otherwise-live pages, in unallocated freelist pages, and — crucially — in the write-ahead log.
The WAL (<db>-wal) and shared-memory (<db>-shm) files deserve special attention. With WAL journaling (the default for most chat apps), new and changed rows are written to the -wal file first and only later "checkpointed" into the main database. The practical consequence for you: the most recent messages — including ones sent moments before the device was seized — may exist only in the -wal file and not yet in the main .db. A naive examiner who copies only msgstore.db and ignores msgstore.db-wal silently loses the freshest, often most relevant, conversation. Always acquire the database and its -wal and -shm companions together — the same discipline as grabbing a registry hive with its transaction logs in Chapter 16. Technology changes, principles don't.
# Illustrative: surface recoverable content from a SQLite chat DB.
# (1) LIVE rows via normal SQL; (2) note that DELETED rows need a carver, below.
import sqlite3
con = sqlite3.connect("file:msgstore.db?mode=ro", uri=True) # READ-ONLY: original is sacred
con.row_factory = sqlite3.Row
for r in con.execute("""
SELECT m.timestamp, c.subject AS chat, j.raw_string AS jid,
m.from_me, m.text_data
FROM message m
JOIN chat c ON m.chat_row_id = c._id
JOIN jid j ON c.jid_row_id = j._id
ORDER BY m.timestamp"""):
# WhatsApp timestamps are Unix epoch MILLISECONDS:
print(r["timestamp"] // 1000, "SENT" if r["from_me"] else "RECV",
r["jid"], "→", r["text_data"])
# DELETED rows are NOT returned by SQL. To recover them, parse free blocks,
# the freelist, AND the -wal file with a SQLite-aware carver:
# undark -i msgstore.db -d --table message
# bring2lite / Epilog / WAL-aware tooling
# These read raw cells the live engine has unlinked but not overwritten.
Tool Tip. Purpose-built SQLite recovery tools —
undark,bring2lite, Epilog, FQLite, and the SQLite recovery built into Cellebrite, Magnet AXIOM, and Autopsy — walk freeblocks, freelist pages, and the WAL to resurrect deleted rows. Run at least two; record counts; and remember the standardsqlite3 .recovercommand rebuilds a corrupt DB but is not a deleted-row carver. Reusable recovery snippets are collected in Appendix B — Python Forensics Toolkit.
WhatsApp — encrypted databases, recoverable contents
WhatsApp is the most common chat artifact worldwide, and its structure rewards study. On Android there are two copies. The working database is unencrypted at /data/data/com.whatsapp/databases/msgstore.db — but that path requires root or a full file-system extraction (Chapter 24). The backup copies sit on shared storage at /sdcard/WhatsApp/Databases/ (newer builds: /sdcard/Android/media/com.whatsapp/WhatsApp/Databases/) as encrypted files: msgstore.db.crypt12, .crypt14, or .crypt15.
WHATSAPP (ANDROID) LAYOUT
/data/data/com.whatsapp/
databases/msgstore.db ← UNENCRYPTED messages (needs root / FFS)
databases/wa.db ← contacts
files/key ← the AES key file (needs root). The 32-byte
AES-256 key is at offset 0x7E (126) of this 158-byte file
/sdcard/.../WhatsApp/
Databases/msgstore.db.crypt14 ← AES-256-GCM encrypted backup
Media/ ← images, video, audio, documents (often plaintext on disk)
The crypt12/crypt14 backups are encrypted with AES-256-GCM. crypt12 and crypt14 use the per-install key stored in the files/key file (the 32-byte key begins at offset 0x7E); crypt14 wraps it in a small protobuf header that also records the cipher and an IV. crypt15 changed the model to end-to-end encrypted backups, where the key is the user's 64-hex-digit (or 64-character passphrase-derived) backup key that WhatsApp never sees — so a crypt15 backup is unrecoverable without that key from the user. The decryption math is real cryptography; without the correct key, an AES-256-GCM backup is not breakable, full stop (theme #5).
# Illustrative ONLY — you must already lawfully possess BOTH the backup and the key.
# Open-source wa-crypt-tools performs the AES-256-GCM decryption:
wadecrypt key msgstore.db.crypt14 msgstore.db # crypt12/14 via the key file
wadecrypt 64-hex-backup-key msgstore.db.crypt15 msgstore.db # crypt15 via user key
# Result: a standard SQLite DB you analyze (and carve for deleted rows) as above.
Once decrypted (or pulled unencrypted), the schema is approachable. Modern builds use a normalized message table joined to chat and jid; older builds use a single messages table with the columns examiners learned first: key_remote_jid (the conversation partner), key_from_me (0 received / 1 sent), key_id (message ID), timestamp and received_timestamp (Unix epoch milliseconds), data (the text), and media_wa_type (0=text, 1=image, 2=audio, 3=video, …). A JID ("Jabber ID," from WhatsApp's XMPP ancestry) ending @s.whatsapp.net is an individual; one ending @g.us is a group. The call_log table records calls; message_media points at files under Media/, which are frequently plaintext on disk even when the database is encrypted — sometimes the media is recoverable when the message text is not. On iOS, the equivalent database is ChatStorage.sqlite inside the app's container, recoverable from an iTunes/Finder backup via the backup's Manifest.db mapping (Chapter 24).
Recovery vs. Forensics. WhatsApp shows the dual lens vividly. A 💾 recovery client whose phone died wants their conversations back: decrypt the latest
.crypt14, hand over a readable archive, done. A 🔍 examiner wants the deleted messages and the metadata: they decrypt, then carve the freelist and-walfor the "this message was deleted" tombstones and the rows the suspect erased, and they preserve every timestamp and JID as evidence. Same database; restore versus reconstruct.
Signal — engineered to resist you
Signal is the honest limit of chat recovery, and you must be able to explain why in court. On Android, messages live in /data/data/org.thoughtcrime.securesms/databases/signal.db, which is SQLCipher — a transparently AES-256-encrypted SQLite. The database key is stored encrypted in shared_prefs, wrapped by a key held in the Android Keystore, which on modern phones is backed by hardware (a TEE or secure element) and does not leave the chip. Practically: without the unlocked, cooperating device (or a vendor exploit), the signal.db is unreadable. On desktop, Signal stores sql/db.sqlite (also SQLCipher) and historically kept its key in plaintext in config.json — a widely discussed weakness; newer builds wrap that key with the OS keychain (Windows DPAPI / macOS Keychain / libsecret), so even the desktop key now generally requires the logged-in user's context.
On top of encryption-at-rest, Signal defaults to disappearing messages (the content is deleted from both devices on a timer), uses sealed sender (the server does not see who sent a message), and retains essentially nothing useful server-side — its widely publicized subpoena responses return little more than account-creation and last-connection dates. The professional posture is to say so plainly: barring the unlocked device and its key, Signal content is generally not recoverable, and "insufficient evidence" is the correct, defensible finding.
Limitation. Do not promise what cryptography forbids. SQLCipher with a hardware-protected key, AES-256-GCM crypt15 backups, and provider-side data Signal never stores are not "hard" — for content, they are effectively impossible without the key or the cooperating, unlocked device. Writing "the data is encrypted and could not be recovered; recovery would require [the device passcode / the user's backup key]" is competent practice. Implying you can break it is not.
Telegram — cloud by default, encrypted device cache
Telegram's central forensic fact is that ordinary chats are cloud chats: stored on Telegram's servers and synced to every device, not end-to-end encrypted (only opt-in Secret Chats are E2E and device-only). That means most Telegram content is a provider-records question (and Telegram's cooperation with legal process is historically limited and jurisdiction-dependent). Locally, Android keeps /data/data/org.telegram.messenger/files/cache4.db — a SQLite file, but its messages_v2 rows store each message as a TL-serialized binary blob (Telegram's MTProto "Type Language" encoding), so you cannot read it as plain text columns; it must be deserialized against the TL schema (tools and AXIOM/Cellebrite parsers do this). On desktop, the tdata\ folder holds the local store, encrypted with a key derived from the local passcode if one is set, or a default-derived key (AES-IGE) if not. Secret Chats exist only on the participating devices and never touch the cloud — recover them from the device or not at all.
Slack, Discord, and Microsoft Teams — Electron caches over cloud truth
These three are Electron desktop apps — effectively a bundled Chromium browser — so their on-disk footprint looks like a browser profile, while the authoritative message store is server-side and reachable for the organization through admin/eDiscovery export or, for outside investigators, legal process.
ELECTRON CHAT APPS — local cache (Windows paths)
Slack %AppData%\Slack\ Cache\, IndexedDB\, storage\, root-state.json, local-settings.json
Discord %AppData%\discord\ Cache\Cache_Data\, Local Storage\leveldb\ (token+settings), Code Cache\
Teams %AppData%\Microsoft\Teams\ IndexedDB\https_teams.microsoft.com_0.indexeddb.leveldb\,
(classic) Cache\, Cookies, storage.json, Local Storage\
Teams %LocalAppData%\Packages\MSTeams_8wekyb3d8bbwe\ ← "new" Teams (WebView2/Edge profile)
(new)
The local caches (Chromium Cache_Data, IndexedDB/LevelDB, Local Storage) can hold recently-viewed messages, channel and user names, cached avatars and attachments, and — in Local Storage/leveldb — authentication tokens. Teams Classic's IndexedDB LevelDB store is notably rich, frequently containing readable cached chat content. But understand the ceiling: these are caches, partial and recency-biased. The complete record lives in the cloud — Slack messages and files in the workspace (recoverable by a workspace admin via the eDiscovery/Discovery API or, on Enterprise Grid, legal hold; by an outsider via process to Slack), Discord messages on Discord's servers, and Microsoft Teams chat in a hidden Exchange Online mailbox folder with files in SharePoint/OneDrive, all governed by Microsoft Purview eDiscovery and legal hold (Chapter 31). For Teams "new," the WebView2 store under the MSIX package path replaces the classic IndexedDB location — the data moved, the method did not.
Recovery vs. Forensics. For 🛡️ incident response inside an organization you control, the fastest path to chat content is almost never the endpoint cache — it is the admin export (Slack eDiscovery, Purview, Google Vault). For an outside 🔍 examiner, the endpoint cache may be all you can lawfully reach until a warrant lands, and it proves local viewing in a way an admin export does not. Know which posture you are in before you spend a day carving LevelDB.
Social media: what is local versus what requires legal process
Facebook, Instagram, X, Snapchat, TikTok, LinkedIn — the pattern repeats. On the device you may recover the app's local cache (the same Chromium/SQLite/LevelDB stores), browser artifacts of web sessions (Chapter 18), downloaded media, push notification remnants, and the occasional offline cache of recently-viewed content. What you will not find locally is the account's authoritative content — posts, direct messages, friend graphs, login history. That lives on the provider's servers, and reaching it is a legal exercise, not a technical one. This is the boundary where forensic technique stops and legal process begins, and crossing it correctly is non-negotiable.
In the United States, stored electronic communications are governed by the Stored Communications Act (SCA), Title II of ECPA, at 18 U.S.C. §§ 2701–2712. The SCA defines a ladder of instruments, each compelling a different class of data at a different legal threshold:
SCA LADDER — what compels what (18 U.S.C. §2703) [criminal process]
┌────────────────────────┬──────────────────┬─────────────────────────────────────────┐
│ INSTRUMENT │ STANDARD │ WHAT IT COMPELS │
├────────────────────────┼──────────────────┼─────────────────────────────────────────┤
│ Preservation request │ §2703(f): a │ FREEZE existing records up to 90 days │
│ ("preservation letter")│ request, no court │ (renewable). NO disclosure yet — buys │
│ │ │ time so data isn't purged. │
├────────────────────────┼──────────────────┼─────────────────────────────────────────┤
│ Subpoena │ §2703(c)(2): │ Basic SUBSCRIBER info: name, address, │
│ │ relevance │ session times & durations, IP/connection │
│ │ │ logs, service length, means of payment. │
├────────────────────────┼──────────────────┼─────────────────────────────────────────┤
│ §2703(d) order │ "specific and │ The above PLUS non-content TRANSACTIONAL │
│ ("d-order") │ articulable │ records / metadata: to/from, logs, │
│ │ facts" │ headers minus body. NOT content. │
├────────────────────────┼──────────────────┼─────────────────────────────────────────┤
│ Search warrant │ PROBABLE CAUSE │ CONTENT: message bodies, photos, stored │
│ §2703(a)/(b) │ (Rule 41 / 4thA) │ files — the substance of the account. │
└────────────────────────┴──────────────────┴─────────────────────────────────────────┘
Three points you must internalize. First, content needs a warrant. Although parts of the older SCA text contemplated compelling content with less, United States v. Warshak (6th Cir. 2010) held that email content carries a reasonable expectation of privacy under the Fourth Amendment, and the practical national standard is now a probable-cause search warrant for content. Treat anything less as inadequate for message bodies. Second, preservation comes first. Providers purge data on their own schedules; a §2703(f) preservation letter — which any investigator can send and which requires no court — freezes the records while you obtain the warrant. Sending it early is often the difference between recoverable and gone. Third, civil cases cannot get content from the provider at all. Section 2702 bars providers from disclosing content to private litigants; cases like Theofel v. Farey-Jones and Crispin v. Christian Audigier confirm a civil subpoena to Facebook or Google for a user's messages will be quashed. In civil litigation you must obtain communications from the party (through discovery, consent, or a forensic exam of their device and accounts) — never from the provider directly.
Legal Note. Match the instrument to the data before you ask. Requesting content with a subpoena, or serving a civil subpoena on a provider for message bodies, does not merely fail — it can taint the investigation and get evidence suppressed. The full framework (Fourth and Fifth Amendments, warrants, consent, the SCA, the CLOUD Act for data held abroad, and MLAT channels for foreign providers) is the subject of Chapter 25 — The Legal Framework, and the mechanics of actually pulling cloud accounts once you have authority are in Chapter 31 — Cloud Forensics. Every major provider publishes a law-enforcement guide specifying exactly what each instrument yields and how to serve it; read the relevant one before drafting.
Ethics Note. This is the chapter where anchor case #4 — the child-exploitation matter — intersects communications, and the handling is procedure and law only. When a provider's automated scanning detects apparent child sexual abuse material, U.S. law (18 U.S.C. §2258A) requires the electronic service provider to report it to the NCMEC CyberTipline; NCMEC routes the report to law enforcement, who then use the SCA ladder above — typically a preservation letter followed by a search warrant — to obtain the account content lawfully. As an examiner you may receive such records, or encounter such material unexpectedly while recovering ordinary communications. Your duties are fixed: stop, do not copy or further view beyond what is necessary, preserve, document, and escalate to the proper authority immediately; mandatory reporting obligations attach. Scope discipline is both legal and humane here — you are authorized to examine this matter, not to browse a person's entire intimate life. The substance of these duties, including examiner well-being and secondary trauma, is owned by Chapter 28 — Ethics. Keep it clinical; never describe content; serve the human need behind the case.
Metadata in communications: the data about the data
Often the metadata of a communication is worth more than its text. A message body can be denied, taken out of context, or claimed to be fabricated; the metadata — recorded automatically by systems with no motive — corroborates, dates, and attributes it.
Timestamps are the most important and the most error-prone. Different platforms use different epochs and resolutions, and a single message can carry several (composed, sent, received-by-server, delivered, read). Convert them carefully and consistently:
TIMESTAMP FORMATS YOU WILL MEET
Format Example value Decodes to
Unix seconds 1710524400 2024-03-15 18:00:00 UTC
Unix milliseconds (WhatsApp) 1710524400000 2024-03-15 18:00:00 UTC (÷1000)
Windows FILETIME (100-ns/1601) 0x01DA76C8... see Ch.16 conversion
Apple/Mac absolute (s/2001) 732218400 + 978307200 → Unix seconds
Apple Core Data (ns/2001) 732218400000000000 ÷1e9, then + 978307200
RFC 5322 header date Tue, 12 Mar 2024 09:41:48 -0400 (note the offset!)
The classic blunder is reading Apple's "seconds since 2001-01-01" as a Unix time and landing 31 years early, or reading WhatsApp's milliseconds as seconds and landing 54,000 years in the future. Each app's epoch is a fact you verify, not assume. And always distinguish client timestamps (set by a device whose clock the user controls) from server timestamps (set by infrastructure) — when they disagree, the server time is usually the more trustworthy anchor, and the disagreement itself can be evidence of a manipulated device clock (every action leaves a trace).
The rest of the metadata catalog: geolocation — shared photos carry EXIF GPS (the domain of Chapter 20 — Photo, Video, and Document Forensics), some platforms tag posts with coarse location, and IP addresses geolocate approximately (city/ISP, not a street); device identifiers — User-Agent/X-Mailer strings, push-notification tokens, and app-internal device GUIDs that can tie an account to a specific handset; message and thread IDs — the Message-ID for email, key_id for WhatsApp, per-platform message/thread identifiers that let you correlate the same item across the sender's copy, the recipient's copy, and a provider return; and receipts and tombstones — delivery and read receipts (proof a message was not just sent but seen), and "this message was deleted"/edited markers that prove a deletion occurred and when, even when the original text is gone. That last one is the theme again: the deletion is itself a dated, recorded event.
Tool demonstration: an email-and-chat pass
A realistic communications examination chains a few tools. Email first, from the verified workstation image:
# 1. Carve/extract Outlook stores from the image, then parse with libpff.
pffinfo WS-ENG-04-mail.ost
File type: Personal Storage Tables (OST), format Unicode (wVer 36)
Encryption type: Compressible (permute) ← obfuscation only; auto-handled
Number of folders: 214 Number of messages: 18,442 Recovered (deleted): 1,107
pffexport -m all -q -t ./ost_out WS-ENG-04-mail.ost
Exported 18,442 items; recovered 1,107 deleted items to ./ost_out/recovered/
# 2. Pull headers from a message of interest and read the Received chain.
exiftool -a -G1 ./ost_out/.../Sent/0421_TurbineHousing.eml # or a header-aware viewer
Then the chat databases, recovered from a mobile extraction (Chapter 24), processed for both live and deleted rows:
# 3. Decrypt the WhatsApp backup (key lawfully obtained), then carve deleted rows.
wadecrypt key msgstore.db.crypt14 msgstore.db
undark -i msgstore.db --table message -d > recovered_messages.csv
Live rows: 9,233 Recovered from freeblocks/freelist/WAL: 614
# 4. Integrated review: Autopsy "Email" + "Android Analyzer" modules, or AXIOM/Cellebrite,
# which parse PST/OST/MBOX, WhatsApp/Signal*/Telegram, and run SQLite recovery,
# presenting threads, attachments, and a unified message timeline.
# (*Signal only when the key/passphrase is available.)
Across both, the rule from Chapter 16 holds: run the load-bearing extraction through two independent tools and confirm they agree on counts, IDs, and timestamps. "I corroborated the recovered messages with libpff and AXIOM, and the deleted-row counts matched" is a sentence that survives cross-examination; tool validation is a Daubert expectation covered in Chapter 27 — Expert Testimony.
Worked example: the engineer's email trail
Return to anchor case #2. The registry (Chapter 16) proved a personal SanDisk was connected and proprietary CAD files were opened from it. Counsel now asks whether the engineer also emailed the designs out. You have the verified image WS-ENG-04.E01 (SHA-256 recorded) and a working copy. You proceed source by source.
1 — The cached corporate mailbox (OST). You carve the OST from the image, hash it, and run libpff. The live Sent Items show nothing incriminating — the engineer cleaned them. But pffexport's recovered/ tree, rebuilt from the OST free space, contains a deleted sent message dated Friday 19:21, from jrivera@corp-victim.com to jr.personal@gmail.com, subject "fyi," with a 41 MB attachment TurbineHousing_pkg.zip. The OST is a cached copy, so this message survived locally even though it was deleted from the server mailbox — deleted is not destroyed.
2 — The headers. You read the recovered message's headers. The Received: chain (bottom-up) confirms it originated on the corporate Exchange server and was relayed outbound at 19:21:07 to Google's MX; Authentication-Results shows the corporate domain's own DKIM pass. The Message-ID is <f29a...@corp-victim.com>. This is not a spoof — it is genuinely the engineer's account sending to a personal Gmail, cryptographically signed by the company's own infrastructure.
3 — The webmail confirmation (browser). Could the engineer claim the email was never actually sent, or that someone forged it? You turn to the browser artifacts (Chapter 18). The Chrome profile shows a mail.google.com session opened on the corporate machine Saturday 09:02, and the offline-Gmail IndexedDB holds a fragment of the jr.personal@gmail.com inbox listing a message "fyi" with attachment TurbineHousing_pkg.zip — received Friday 19:21. The recipient side corroborates the sender side, on the same physical machine, in the same account the engineer logged into.
4 — Correlate to the device timeline. The Message-ID and timestamps thread directly into the Chapter 16 timeline:
WS-ENG-04 — COMMUNICATION EVENTS merged into the case timeline (UTC), user jrivera
Fri 18:51 SanDisk Cruzer Glide connected → E: [USBSTOR/MountPoints2] (Ch.16)
Fri 19:04 Opened TurbineHousing_v7.sldprt FROM E: [LNK + Jump List] (Ch.16)
Fri 19:21 Email "fyi" w/ TurbineHousing_pkg.zip (41 MB) → gmail [RECOVERED OST item] (Ch.19)
Fri 19:21 Outbound relay to Google MX; corp DKIM=pass [Received chain] (Ch.19)
Sat 09:02 mail.google.com session on corp machine (jr.personal) [browser history] (Ch.18)
Sat 09:02 Gmail offline IndexedDB shows "fyi" + attachment received [IndexedDB fragment] (Ch.19)
Sat 09:12 CAD files sent to Recycle Bin; 09:14 CCleaner run [$I / Prefetch] (Ch.16)
The email did not merely exist — it was sent at the same console session as the USB copy, to a personal account the engineer then logged into from the corporate machine, and the recipient-side cache confirms delivery. The deletion of the Sent item, far from hiding it, sits in the recovered free space as one more dated event.
War Story. An examiner on a near-identical matter nearly missed the case-making email because the live Sent Items were empty and the first-pass tool only listed active folders. It was the
recovered/output of a forensic PST parser — the deleted-item reconstruction from free space — that surfaced the message. The lesson is the one this chapter keeps making: in communications, the deleted material is frequently the evidence, and a tool that shows you only the live mailbox is showing you the version the suspect wanted you to see. Always run the recovery pass, and always read what was thrown away.Chain of Custody. Every artifact above traces to the hashed image: "Recovered deleted item
0421from OST carved fromWS-ENG-04.E01(SHA-256a3f1…); working OST MD5c7b9…; extracted with libpff 20231205; corroborated in Magnet AXIOM." The Gmail IndexedDB fragment is similarly sourced to the Chrome profile path and hashed. A finding you cannot trace back to a verified image is a finding you cannot defend — the discipline established in Chapter 14 — Forensic Acquisition and Chapter 5 — The Forensic Process.
Common mistakes
- Copying the chat database but not its
-waland-shm. The most recent messages may live only in the write-ahead log. Acquiredb,db-wal, anddb-shmtogether, or you silently lose the freshest conversation — the exact analogue of grabbing a registry hive without its transaction logs. - Reading the
Received:chain top-down. The origin is at the bottom. Reading top-down inverts the trace and leads you to name the recipient's own server as the source. - Trusting
Received:headers below your trust boundary. Everything beneath the first server you control can be forged by the sender. Anchor your conclusions to the header written by infrastructure you trust. - Confusing SPF pass with a genuine sender. SPF authenticates the envelope (
MailFrom), not the visibleFrom:. A message can pass SPF and still display a forgedFrom:; only DMARC alignment ties authentication to what the victim sees. - Treating a PST "password" or "encryption" as a real barrier. The password is a CRC the parser ignores; "compressible"/"cyclic" encryption is reversible obfuscation. Do not report a routine PST as cryptographically protected.
- Assuming social-media content can be subpoenaed from the provider. Content requires a warrant (Warshak), and in civil cases the SCA bars the provider from disclosing content at all — you must get it from the party. Using the wrong instrument can suppress the evidence.
- Forgetting to send a preservation letter early. Providers purge on their own schedules. A §2703(f) preservation request — no court needed — freezes records while you obtain the warrant. Sent late, the data may already be gone.
- Misreading an epoch. Apple "seconds since 2001," Unix seconds, and WhatsApp milliseconds are not interchangeable. Verify each platform's timestamp format before you build a timeline, or you will be decades off.
- Reporting "no messages found" on Signal as if it were a search failure. It is an architectural fact. State that the content is encrypted with a hardware-protected key and is not recoverable without the unlocked device/key — that is the competent finding, not a deficiency in your work.
- Over-collecting beyond scope. Communications implicate third parties who are not subjects of your investigation. Pull what your authority covers; do not browse a custodian's entire intimate correspondence because you can.
Limitations: knowing when to stop
Communications forensics has hard ceilings, and a professional report states them as clearly as its findings. The largest is strong encryption you do not have the key for: Signal's SQLCipher with a hardware-backed key, WhatsApp's AES-256-GCM crypt15 backups keyed by a passphrase the provider never sees, and end-to-end encrypted message bodies in transit are not "difficult" — without the key or the unlocked, cooperating device they are effectively impossible, and "the content is encrypted and could not be recovered" is the correct conclusion (theme #5).
A subtler limit is the device-versus-cloud boundary. The endpoint holds caches — partial, recency-biased, sometimes stale; the authoritative record lives on the provider's servers, behind a legal process you may not be authorized to invoke. Recovering a Slack cache does not give you the workspace's full history, and a Gmail IndexedDB fragment is not the mailbox. Be precise about which you have, and never present a cache as the complete account.
Deleted-row recovery from SQLite degrades over time and use. Free blocks are reused by new inserts; a VACUUM (which some apps run automatically) erases them outright; and a -wal checkpoint plus truncation can remove the only copy of a recent message. The longer a live device runs after a deletion, the less you will recover — which is itself an argument for prompt, proper acquisition. Carving also reconstructs rows, not necessarily context: a recovered message cell may have lost its association with a chat or contact, and you must be careful attributing an orphaned row to a conversation.
Finally, metadata can be manipulated, and absence is ambiguous. Device clocks can be set, client timestamps forged, headers fabricated below the trust boundary. You defend against this by correlation — server timestamps against client, one party's copy against the other's, communication events against independent system artifacts — and by stating findings as the corroborated inferences they are. When the sources genuinely conflict and cannot be reconciled, "the available evidence is insufficient to determine whether this message was sent at the stated time" is a valid, defensible finding. Forcing a conclusion the data will not bear is how communications evidence collapses on cross-examination.
Progressive project: recover the communication evidence (email and chat) for the case
Continue building your Forensic Case File (introduced in Chapter 5 — The Forensic Process, acquired in Chapters 14–15, and layered with system artifacts in Chapters 16–18). This chapter you add the communications layer.
- Email. From your verified image, locate and carve any Outlook stores (search for the
!BDNheader), MBOX files (theFromseparator), and loose EML/MSG. Hash each extracted store and log it on your chain-of-custody worksheet (template in Appendix F). Runlibpff(or Autopsy's Email module) with deleted-item recovery enabled; export therecovered/tree as well as the live folders. For the single most relevant message, capture the full headers, read theReceived:chain bottom-up, and record the originating IP, the SPF/DKIM/DMARC results, and the Message-ID. - Chat. From your mobile/disk extraction, identify every chat SQLite database and acquire each with its
-waland-shm. For any WhatsApp.crypt12/14backup, decrypt it only if you lawfully hold the key, and document where the key came from. Run a SQLite deleted-row carver (e.g.,undark) over each database; record live-row and recovered-row counts. Note any database you cannot read (Signal, crypt15 without key) and write the honest limitation. - Webmail and social media. From the browser artifacts (Chapter 18), document any webmail or social-media use: history, cache fragments, and the Gmail/Service-Worker IndexedDB. For each account whose content lives in the cloud, write one line identifying the correct legal instrument to obtain it (preservation letter → warrant for content) and note that the cache proves only local access.
- Metadata and timeline. Normalize every communication timestamp to UTC, recording each platform's epoch. Add a communications timeline to the case file, every entry sourced to an artifact, and merge it with your Chapter 16–18 timeline. For each load-bearing finding, corroborate with a second tool and flag any limitation (cache-not-account, deleted-row-without-context, device-versus-server time) so future-you reports it honestly.
Save every export, count, and the timeline into the case-file folder. You will fold this into the master timeline in Chapter 21, the report in Chapter 26, and the final assembly at the capstone, Chapter 38.
Summary
Communications are where intent lives, and this chapter taught you to recover them across the full spectrum from the device to the cloud. On the email side you learned to recognize the formats on sight — Outlook's PST/OST (the !BDN header, ANSI versus Unicode by the version word, the layered NDB/LTP/Messaging structure, a "password" that is only a CRC and "encryption" that is only reversible obfuscation, and deleted items that linger in free space until compaction), the Unix-lineage MBOX with its From separator, single-message EML/EMLX, and the CFB-based MSG — and to recover from each with libpff, readpst, or carving, exploiting the fact that an OST is a cached time capsule that often outlives the server copy. You learned to trace a message to its origin by reading the Received: chain bottom-up to the trust boundary, and to test sender authenticity with SPF (envelope only), DKIM (cryptographic integrity), and DMARC (alignment to the visible From:), with the spoofed-PayPal headers as your worked specimen. You saw that webmail leaves its evidence in the browser — history, cache fragments, and Gmail's offline IndexedDB — which proves local access even when the mailbox itself requires a warrant.
On the chat side you learned the unifying technique: almost everything stores messages in SQLite, deleted rows survive in free blocks, the freelist, and especially the -wal until reuse or VACUUM, and a SQLite-aware carver resurrects them — deleted is not destroyed. You walked the major apps and exactly what is and is not encrypted: WhatsApp's msgstore.db and its AES-256-GCM crypt12/14/15 backups (recoverable with the key, impossible without it), Signal's SQLCipher store with a hardware-protected key (generally unrecoverable by design), Telegram's cloud-by-default model with TL-serialized local cache and device-only Secret Chats, and the Electron trio — Slack, Discord, Teams — whose local caches are partial while the authoritative record sits in the cloud behind admin export or legal process. You learned the social-media boundary in law, not just in technique: the SCA ladder from a §2703(f) preservation letter through subpoena and §2703(d) order to the probable-cause warrant that content requires after Warshak, and the civil-case bar that sends you to the party rather than the provider. You catalogued the metadata that often outweighs the text — the epoch-sensitive timestamps, geolocation, device identifiers, message IDs, and the receipts and tombstones that prove a message was seen or deleted — and you reassembled the engineer's email trail, where a deleted sent item recovered from OST free space, its DKIM-signed headers, and a recipient-side webmail cache fragment turned a USB-copy case into a documented exfiltration. Through all of it the method held constant: recognize the format, acquire the whole of it (database and logs), recover the deleted along with the live, obtain cloud content by the correct legal instrument, corroborate across sources, and state every finding with its limits.
You can now: - Identify and recover the major email formats — PST/OST (including deleted items and orphaned/stale OSTs), MBOX, EML/EMLX, and MSG — and explain why the PST password and "encryption" are not real barriers. - Trace an email to its origin by reading the
Received:chain bottom-up to the trust boundary, and assess sender authenticity with SPF, DKIM, and DMARC. - Recover webmail evidence from browser cache and IndexedDB, distinguishing proof of local access from the account content that requires legal process. - Recover live and deleted chat messages from SQLite (free blocks, freelist, and the-wal), and explain what is recoverable per app — WhatsApp, Signal, Telegram, Slack, Discord, and Teams. - Map social-media data to the correct legal instrument on the SCA ladder (preservation letter, subpoena, §2703(d) order, search warrant) and apply the civil-versus-criminal distinction. - Decode communication metadata across epochs and platforms, normalize timestamps to UTC, and report findings — including encryption limits and cache-versus-account boundaries — honestly and defensibly.
What's next. Chapter 20 — Photo, Video, and Document Forensics — follows the attachments this chapter kept finding: you will read EXIF GPS and camera data, detect manipulated and AI-generated images, recover Office and PDF internal metadata, and authenticate media — the evidence type at the heart of anchor case #4, handled, as always, clinically.
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.