Forensics Git 2: Recovering Deleted Directory Trees & Git Artifacts

Investigating a raw 1 GB ext4 disk image (disk.img) containing a developer repository (killer-chat-app). In the repository's log archive, files 1.txt, 2.txt, and 4.txt are present, but 3.txt is missing. Through Git reflog analysis, we discover that Commit 4 ("Add secret hideout chat log") added the file before Commit 5 deleted it. By walking Git's hierarchical nested tree objects (Commit → Root Tree → Subdirectory Tree → Blob), we carve the deleted blob from the ext4 filesystem and decompress the hidden secret.
01. Spotting the Sequence Anomaly & Reflog Triage
After locating the primary ext4 filesystem at Sector offset 1140736 via mmls, we inspect user space using fls:
fls.exe -o 1140736 -r .\disk.img 64770To determine what happened to 3.txt, we dump Git's reflog history from logs/HEAD (Inode 65707):
icat.exe -o 1140736 .\disk.img 6570702. Multi-Tiered Git DAG Traversal (Commit → Root → Subtree → Blob)
Because 3.txt was placed inside a subdirectory (logs/), Git maintains a hierarchical tree structure. Each directory level is its own separate tree object (mode 40000).
python -c "import subprocess, zlib; print(zlib.decompress(subprocess.check_output(['icat.exe', '-o', '1140736', '.\disk.img', '65735'])))"python -c "import subprocess, zlib; print(zlib.decompress(subprocess.check_output(['icat.exe', '-o', '1140736', '.\disk.img', '65734'])))"python -c "import subprocess, zlib; print(zlib.decompress(subprocess.check_output(['icat.exe', '-o', '1140736', '.\disk.img', '65732'])))"03. Inflating the Hidden Chat Log & Flag Capture
Having located the raw zlib-compressed object for 3.txt at Inode 65730, we execute an automated extraction script:
import subprocess
import zlib
inode = "65730" # Inode for 3.txt compressed blob (hash 717864...)
cmd = ["icat.exe", "-o", "1140736", ".\\disk.img", inode]
raw_compressed = subprocess.check_output(cmd)
decompressed = zlib.decompress(raw_compressed)
print(decompressed.decode('utf-8', errors='ignore'))