Step 243. Disk Forensics: Autopsy, Deleted-File Recovery — What’s Deleted Isn’t Gone

Step 243. Disk Forensics: Autopsy, Deleted-File Recovery — What’s Deleted Isn’t Gone

Level 3 — Forensics Track | Difficulty ★★★★☆ | Estimated time: 5 hours

Prerequisites: Step 239 (signatures, carving) and Step 242 (memory-forensics principles) complete.

⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.

  • What you need: Python 3 (measured: 3.12.14), the file command on WSL.
  • Caution: Autopsy isn’t available in this environment, so it’s introduced as a "Screen example." Instead, the reality of deletion — "deleting = flipping a marker" — is fully measured on a FAT12 disk image you build yourself in Python. No mounting, no system changes; the image file is only read as bytes.

Where does a file go when you empty the Recycle Bin? The answer is — nowhere. The filesystem merely flips a marker that says "this spot is free to use" and leaves the data right where it was. That’s why recovery is possible until the space gets overwritten, and why a file a suspect deleted becomes courtroom evidence. Today you prove this principle by building a toy disk image with your own hands, then confirm that what the real-world tool Autopsy shows on screen is exactly this principle visualized.


1. Learning Objectives

By the end of this chapter, you will be able to:

  • Explain structurally that filesystem deletion is "deallocation," not "data erasure"
  • Know how a FAT directory entry and the FAT chain record a file’s location
  • Recover a file byte-for-byte by scanning deleted entries (0xE5)
  • Explain why remnants of old data survive in slack space
  • Know what Autopsy’s deleted-files view, keyword search, and timeline each show

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment Python 3 (measured: 3.12.14) + WSL file 5.45 — the image is generated and parsed in pure Python
Today’s code Directory-entry parsing (struct.unpack), 0xE5 scanning, cluster-chain tracing
Concepts needed Clusters, directory entries, FAT chains, slack space, unallocated space
Today’s deliverable A FAT12 image + a deletion simulation + a recovered file (byte-identical to the original)

2-1. The Filesystem’s Ledger — Where a File Is Recorded

On disk, a single file is recorded across three places. ① Directory entry: one line in the ledger with name, start location, size, and timestamps. ② Allocation table (the FAT chain in FAT, $BITMAP in NTFS): whether each region (cluster) is free or used, and where the next region is. ③ Data area: the actual contents.

When you open a file, the operating system reads the start location and size from ①, follows ②, and gathers ③. Knowing this ledger structure is everything there is to understanding deletion and recovery.

2-2. The Reality of Deletion — Only Two Markers Change

Here’s exactly what happens when you delete a file on FAT:

  1. The first byte of the directory entry becomes 0xE5 — "this line is empty"
  2. The file’s clusters in the allocation table become 0 — "these regions are free to use"

The data area (③) is untouched by anyone. If deletion also overwrote the data, deleting a multi-GB file would take minutes — this design was born for efficiency. NTFS is the same in essence (clear the "in use" bit of the $MFT entry and release $BITMAP). Deletion isn’t incineration; it’s attaching a "free to discard" tag. While the physical item remains with the tag attached — until new data overwrites that spot — recovery is possible.

2-3. Slack Space — Between the End of the File and the End of the Cluster

A filesystem hands out space only in cluster units (512 bytes here). A 700-byte file receives 2 clusters (1024 bytes), and the trailing 324 bytes come along without being file content — this is slack space. If data from an older file sits there, writing a new file won’t touch anything past the new file’s end, so the remnants survive. This is the classic route by which forensics surfaces information that’s "not in any file but on the disk."

2-4. Autopsy — These Principles, Visualized (Screen Example)

Autopsy (the Sleuth Kit’s GUI) tears open a disk image and shows these structures on screen. It’s not in this environment, so here’s a Screen example (not actually executed):

# Screen example — the Autopsy analysis flow
1. New Case → Add Data Source → choose a disk image (.img/.E01)
2. Left tree: Views → Deleted Files   ← collects 0xE5 entries and unused $MFT records
3. Click a file → content preview at the bottom → Extract to recover
4. Keyword Search: search the whole image for "password" etc. (options to include unallocated space & slack)
5. Timeline: arrange file create/modify/delete times on a time axis → reconstruct user behavior

The Deleted Files view is a collection of the 0xE5 lines from 2-2, and searching unallocated space is digging directly through data that has only lost its tag. What we’ll do in Python today is the principle behind those screens.


3. Follow Along

3-1. Building a Toy Disk — Assembling a FAT12 Image by Hand

Assemble a 1.44MB image byte by byte, following the real FAT12 spec. The order is boot sector (BPB), two copies of the FAT, root directory, data area (full script at tmp_test/step243_fat.py; only the core here. All output in this chapter measured 2026-09-09):

import struct
SECTOR = 512
img = bytearray(2880 * SECTOR)          # 1.44MB floppy format
# Boot sector: bytes/sector, sectors/cluster, number of FATs, root entries ...
img[510:512] = b"\x55\xaa"              # boot signature
# ... initialize the FAT, write SECRET.TXT (700 bytes) to clusters 2–3,
#     register (name, start cluster 2, size 700) in the directory entry,
#     set the FAT chain 2 → 3 → EOF(0xFFF)
open("s243_floppy.img", "wb").write(bytes(img))
① Image created: s243_floppy.img (1.44MB, FAT12)
   SECRET.TXT 700 bytes = clusters 2–3, FAT chain 2→3→EOF

Whether this image is genuine gets proven by Step 239’s tool:

file s243_floppy.img
s243_floppy.img: DOS/MBR boot sector, ..., OEM-ID "KIMIFAT ", root entries 224,
sectors 2880 (volumes <=32 MB), sectors/FAT 9, sectors/track 18, ..., FAT (12 bit ...)

(Measured 2026-09-09.) file recognized this blob of bytes as a FAT12 filesystem — proof that we assembled it to spec, and a confirmation that a filesystem, too, is ultimately "agreed-upon bytes in agreed-upon places."

3-2. Reproducing the Reality of Deletion — Flip Just Two Markers

Now "delete" SECRET.TXT from this image. Exactly the procedure from 2-2:

ent = bytearray(img[ROOT0:ROOT0+32])
ent[0] = 0xE5                        # first byte of the directory entry → 'empty'
img[ROOT0:ROOT0+32] = ent
fat_set(2, 0); fat_set(3, 0)         # release the FAT chain → 'free to use'
open("s243_deleted.img", "wb").write(bytes(img))
② Deletion simulated: directory first byte→0xE5, FAT chain→0 (data area untouched)

(Measured 2026-09-09.)

How to read it: the changed bytes are exactly 1 byte (the entry’s first character) + 2 FAT entries. The 700 bytes in the data area didn’t change by a single byte. This is all that "deletion" is. It’s gone from the file manager, but it’s still on the disk.

3-3. Recovery — Find the 0xE5 Entry and Retrace the Chain

Do with your own hands what a recovery tool does. Sweep the root directory for an entry starting with 0xE5 (a deleted one), then read the data using the start cluster and size still recorded there:

d = open("s243_deleted.img", "rb").read()
for i in range(224):                              # census of all 224 root entries
    e = d[ROOT0 + i*32 : ROOT0 + (i+1)*32]
    if e[0] == 0xE5 and e[11] == 0x20 and (e[26] | e[27]):
        name = "?" + e[1:8].decode().strip() + "." + e[8:11].decode().strip()
        clus, = struct.unpack("<H", e[26:28])     # the start cluster survives
        size, = struct.unpack("<I", e[28:32])     # the size survives too
        print(f"found: {name}  start cluster {clus}, size {size} bytes")
        data = d[DATA0 : DATA0 + ((size + 511)//512)*512][:size]
        open("s243_recovered.txt", "wb").write(data)
        print("matches original:", data == SECRET)
③ Recovery begins — scanning the root directory for 0xE5 entries:
   found: ?ECRET.TXT  start cluster 2, size 700 bytes
   recovery saved: s243_recovered.txt — first line: DH{d3l3t3_1s_n0t_3r4s3}
   matches original: True

(Measured 2026-09-09.)

How to read it: notice three things. ① The filename’s first letter is ? — because the first byte was overwritten with 0xE5. The ?ECRET.TXT-style names real recovery tools show are exactly this. ② The start cluster and size remain in the entry, becoming the thread of the recovery. ③ The recovered file matches the original byte for byte (True) — a complete proof that "deletion is not erasure." One caveat: since the FAT chain was released, the position of the second cluster onward relies on the assumption "it was probably contiguous" — if the file had been fragmented, recovery gets hard from this point.

3-4. Remnants in Slack Space

This time, look past the end of the file. The 324 bytes after the 700-byte file’s last cluster — the slack space:

slack = d[DATA0 + len(SECRET) : DATA0 + 2*SECTOR]
print(slack.split(b"\x00")[0].decode(errors="replace"))
④ Slack-space check — the region after the file end (700) in cluster 3:
   remnant found: OLD_PASSWORD=hunter2 (remnant of an older file)

(Measured 2026-09-09 — old data we planted in advance was sitting intact past the file’s end.)

How to read it: a string that exists nowhere in the current file exists on the disk. This spot is why you turn on the "include unallocated & slack" option in Autopsy’s keyword search. Deleted passwords and earlier drafts of overwritten documents come out of cracks like this at real scenes.

3-5. Reality Adjustments — When Recovery Fails

Today’s experiment succeeded cleanly because we wrote nothing after deleting. Let’s organize reality’s constraints:

  • Overwriting: once new data is written into a released cluster, that part is finished. That’s why recovery tools say "the moment you notice a deletion, stop using that drive."
  • Fragmentation: once the FAT chain is released, the next cluster’s position is lost. If storage wasn’t contiguous, you fall back to header/footer carving (Step 239).
  • SSD TRIM: modern SSDs have the controller actually empty the cells upon deletion. "Deletion ≠ erasure" is an HDD-era principle that’s half broken on SSDs — the reality of forensics is changing too.
  • Secure wipe: tools like shred and cipher /w actually overwrite the data area. Deletion and erasure are different verbs.

4. Missions & Exercises

Mission — Building and Dissecting a Two-File Incident Image

  1. Extend 3-1 to build an image recording two files (NOTE.TXT, KEY.TXT — on different clusters)
  2. "Delete" only one of them (0xE5 + chain release)
  3. Run the recovery script to selectively recover the deleted one, and show that the living file is still listed normally in the directory
  4. (Challenge) Partially overwrite the deleted file’s second cluster with a new file’s data, then observe and record how the recovery result degrades

Exercises

Problem 1. Name the two things that change when a file is deleted on FAT, and the one thing that doesn’t.

Problem 2. Explain, using the directory-entry structure, why the recovered filename comes out as ?ECRET.TXT.

Problem 3. A 700-byte file was allocated 2 clusters (1024 bytes). How many bytes is the slack space, and why can old data remain there?

Problem 4. Explain why the same "deletion" is hard to recover on an SSD (TRIM) but recoverable on an HDD, and what a secure-wipe tool like shred does.


5. Model Answers & Completion Criteria

Mission Model Answer

Core structure — register the two files’ entries and chains side by side:

# NOTE.TXT → cluster 2, KEY.TXT → cluster 4 (spacing them out makes tracing easy)
write_file(img, b"NOTE    TXT", 2, note_data)
write_file(img, b"KEY     TXT", 4, key_data)
# Delete only KEY.TXT: entry[0]=0xE5, fat_set(4, 0)

The recovery script selects only the 0xE5 entry (KEY.TXT), while the normal entry (NOTE.TXT) — whose first byte isn’t 0xE5 — appears in the "living files" list. The very fact that these two lists split is the principle behind Autopsy’s regular file view and Deleted Files view.

Expected result for challenge 4: starting from the overwritten part, new data appears and the file contents get scrambled. The point where matches original becomes False is the "recovery limit line," and salvaging at least the header portion with carving (Step 239) is the next step’s thread.

How to verify: ① Are living and deleted files listed separately? ② Does the recovered file match the original? ③ In the challenge, did you record from which offset the corruption begins?

Exercise Answers

Answer 1. What changes: ① the directory entry’s first byte becomes 0xE5, ② the FAT chain becomes 0 (deallocation). What doesn’t change: the actual contents in the data area — which is why 3-3 recovered the file byte-identical to the original.

Answer 2. Because FAT’s deletion marker works by overwriting the entry’s first byte with 0xE5 — and that first byte is where the filename’s first letter lives. The remaining 7 letters and the extension survive, so it shows as ? + ECRET.TXT. This is why recovery tools ask you for the first letter of the name.

Answer 3. 1024 − 700 = 324 bytes. A filesystem allocates only in cluster units, and writing a file fills data only up to the file’s length. From the file’s end to the cluster’s end, whatever data previously occupied that spot remains unerased — because nobody overwrote that region.

Answer 4. On an HDD, deletion is a ledger-marker change so the data lingers as magnetism; on an SSD, once a TRIM command goes down, the controller actually empties the block’s cells and reads come back as 0. A secure-wipe tool bypasses the OS’s deletion and directly overwrites the data area with random data or zeros (often multiple times), removing the very premise of recovery. "Deletion (ledger)" and "erasure (overwriting)" are different verbs.

Completion Criteria Checklist

  • [ ] I can explain that a file is recorded in three places: directory entry, allocation table, data area
  • [ ] I confirmed by experiment that deletion = 0xE5 + chain release, with the data left intact
  • [ ] I recovered a deleted file via 0xE5-entry scanning and compared it against the original
  • [ ] I read out a remnant from slack space myself
  • [ ] I can name the three conditions that defeat recovery (overwriting, fragmentation, TRIM)
  • [ ] I know the principles behind Autopsy’s Deleted Files, keyword search, and timeline
  • [ ] Mission: completed building, deleting, and recovering on the two-file incident image

6. Common Pitfalls & Fixes

Wall 1. You recovered a file but it’s corrupted

Symptom: extraction worked, but the contents are scrambled.
Cause: part of the deallocated clusters was overwritten with new data, or the file was fragmented and the "contiguous" assumption was wrong.
Fix: if the header (signature) survives, use Step 239’s carving to sort out the salvageable part. "Partial recovery is still evidence" — even if only the first line remains, the fact that it existed is proven.

Wall 2. You found a 0xE5 entry but the start cluster is 0

Symptom: the entry exists but its location fields are empty.
Cause: some operating systems and tools erase the location fields on deletion too, or the entry has been recycled.
Fix: switch to carving — scanning all unallocated space for signatures. When entry-based recovery fails, go content-based — that’s why two layers of tools exist.

Wall 3. Your FAT12 entry math is off

Symptom: your hand-written fat_get/fat_set returns strange values.
Cause: FAT12 has 12-bit entries, so two entries share 3 bytes. Even and odd clusters lay their bits out differently.
Fix: even clusters use the lower 12 bits, odd the upper 12 — the branch in the practice code handles it. If the math feels suspect, write 3 into cluster 2 and read it back immediately for a round-trip check.

Wall 4. Recovery fails even right after deletion (SSD)

Symptom: a file deleted from a USB stick or SSD reads back as zeros only.
Cause: TRIM — the controller actually emptied the block. The firmware did the erasing, not the OS’s deletion.
Fix: "not recoverable" is the correct conclusion. In a forensic report, "erased via TRIM" is a legitimate observation. Recording the device type (HDD/SSD) and whether TRIM is active first is standard field procedure.

Wall 5. Autopsy can’t open the image

Symptom (Screen example): Add Data Source doesn’t recognize the image.
Cause: the image may be a dump of a single partition rather than a whole physical disk, or the dump may be damaged.
Fix: partition images usually open too (add it as a partition). If it still fails, identify it first with file image — Step 239’s first move applies here exactly the same.


7. Summary

Today’s Concepts

Concept One-line explanation
Ledger structure A file = directory entry + allocation table + data area, three records
The reality of deletion One 0xE5 byte + chain release — the data stays
0xE5 scanning The principle of recovery: find deleted entries, use the start cluster and size
Slack space Between file end and cluster end — the storage locker for old data’s remnants
Recovery’s limits Overwriting, fragmentation, TRIM — the three things that defeat recovery
Deletion vs erasure Ledger-marker change vs data overwriting — different verbs

Today’s Commands & Code

Command/code What it does
file image Identify the image’s filesystem (confirm FAT12 recognition)
entry[0] = 0xE5 FAT-style deletion — "this line is empty"
Unpacking e[26:28], e[28:32] Read start cluster and size from a deleted entry
The 0xE5 scan loop Restore the deleted-files list (the principle of the Deleted Files view)
Autopsy (Screen example) Image browsing, deleted-file recovery, keyword search, timeline

An Instinct More Important Than Commands

Today’s key sentence — "delete" is close to a verb that doesn’t exist in computing. It flips a marker; the data sits there until overwritten. This fact cuts in two directions. For the analyst it’s hope (deleted evidence can be recovered); for the user it’s a warning (important files must be erased, not deleted).

And with this chapter, the Forensics track’s three axes are in place — files (239), memory (242), disk (243). You’ve seen the single principle running through all three: every record splits into ledger and substance, and evidence hides in the mismatch between them. A file’s extension and its signature, the process registry and memory traces, the directory entry and the data area — forensics is the technique of reading this gap.


Once every box is checked, Step 243 is complete. Click the checkbox in the sidebar to save your progress.