Description
The agents interrupted the perpetrator's disk deletion routine. Can you recover this git repo?
Setup
Download and decompress the disk image.
Mount the image and inspect the filesystem for a damaged git repository.
gunzip disk.img.gzsudo mount -o loop disk.img /mnt/diskSolution
- Step 1Decompress and quick strings checkExtract the disk image. The deletion routine was interrupted, so git objects may still be present. Run strings first as a fast check.
gunzip disk.img.gzstrings disk.img | grep picoCTFLearn more
When a deletion process is interrupted, the filesystem may be in an inconsistent state: some files are deleted (their directory entries removed) but their data blocks have not yet been overwritten. The raw bytes of the deleted content remain on disk until the operating system reuses those blocks for new data.
strings | grep picoCTFscans the raw image and finds these bytes even though the filesystem no longer has a path to them.This is the principle behind file carving: recovering files by their content patterns rather than their filesystem metadata. Known file types have recognizable headers (magic bytes) — for example, JPEG files start with
FF D8 FF, ZIP files with50 4B 03 04, and git objects are zlib-compressed with a characteristic header. Carving tools like Foremost and PhotoRec scan raw disk images looking for these magic bytes and extract complete files even from unallocated space. - Step 2Detect partition layout and mountUse mmls to identify the partition offset, then mount the filesystem.
mmls disk.imgsudo mount -o loop,offset=$((512*<start_sector>)) disk.img /mnt/diskls /mnt/diskLearn more
Even when files are deleted, the partition table and filesystem superblock are usually intact because they are written early in the deletion process and are often the last to be cleared.
mmlsreads the partition table to locate the data partition, and Linux can still mount and read the filesystem structure even if individual file inodes have been cleared.Linux ext4 filesystems mark deleted inodes as free in the inode bitmap but do not immediately zero the inode's block pointers. This means the Sleuth Kit's
ils(inode list) andifindtools can still see deleted inodes and their data block addresses for a period after deletion — long enough to recover recently deleted files. Thefls -r -dcommand from TSK lists deleted files and directories by scanning for inodes marked as unallocated. - Step 3Find surviving git objectsSearch for .git directories or HEAD files that survived the partial deletion. If the repository directory is gone, scan for loose object files.
find /mnt/disk -name '.git' -type d 2>/dev/nullfind /mnt/disk -name 'HEAD' 2>/dev/nullfind /mnt/disk -path '*/objects/*/*' 2>/dev/null | headLearn more
Git loose object files are stored in
.git/objects/XX/YYYYYYYY...whereXXis the first two hex characters of the object's SHA-1 hash. Each file is zlib-compressed and contains either a blob (file content), tree (directory snapshot), commit (history entry), or tag. Even if the.gitdirectory itself was deleted, individual object files that haven't been overwritten can be recovered and reassembled.The
HEADfile in a git repository contains a ref pointer likeref: refs/heads/mainor a raw SHA-1 hash (detached HEAD). Finding an intactHEADfile tells you the repository's root and whether the ref structure survived. IfHEADis gone but object files remain, you can still reconstruct history by runninggit fsckin a directory containing those object files.Git also supports pack files (
.git/objects/pack/*.pack) which bundle many objects into a single compressed archive with a corresponding index file. Pack files are more space-efficient than loose objects and are created bygit gcor when fetching from a remote. If pack files survived, they may contain all the repository's history even if loose objects were deleted. - Step 4Recover the repositoryCopy any surviving git directory or objects to a writable path and run git fsck to reconstruct reachable history.
mkdir /tmp/recovered && cp -r /mnt/disk/<path>/.git /tmp/recovered/.gitcd /tmp/recovered && git fsck --unreachablegit log --all --oneline 2>/dev/nullgit fsck --lost-found && ls .git/lost-found/other/Learn more
git fsck(filesystem check) verifies the integrity of the object database. It traverses all refs and objects, checks SHA-1 hashes for corruption, and reports dangling (unreachable) objects. Running it after recovering partial object files tells you which parts of the history survived and whether any objects are corrupt (truncated or overwritten blocks).If
git logreports errors about missing objects, you can sometimes reconstruct the missing pieces by finding their raw bytes in the disk image usinggrepfor the partial SHA-1 hash, or by usinggit hash-object -wto re-add a found blob. The recovery process is iterative: find surviving objects, identify which are missing, search for them in unallocated space, and repeat until the history is complete enough to read the flag. - Step 5Use TSK to recover deleted files if neededIf the .git directory itself was deleted, use The Sleuth Kit to recover deleted inodes from the raw image.
fls -r disk.img | grep -i giticat disk.img <inode> > recovered_objectfile recovered_objectLearn more
The Sleuth Kit (TSK) provides low-level filesystem access.
fls(file list) lists files and directories, including deleted ones (marked with*). It uses inode metadata rather than directory entries, so it finds files even after their directory entries are removed.-rrecurses into directories and-dfilters for deleted entries only.icat(inode cat) reads the data blocks of a specific inode and writes the raw file content to stdout. This works even for deleted inodes as long as their block pointers haven't been reused. Each git object file recovered this way is a zlib-compressed blob. You can verify it withfile(which recognizes zlib streams) and add it to a recovered git repository withgit hash-object -w recovered_objectafter decompressing.This level of filesystem forensics is used in real criminal investigations. Law enforcement agencies routinely recover deleted files from seized devices using tools like TSK, EnCase, and FTK (Forensic Toolkit). The key insight is that deletion on most filesystems is a metadata operation — it removes the directory entry and marks the inode as free, but the actual data remains until overwritten.
- Step 6Extract the flagRead flag content from whichever commit, blob, or recovered file contains it.
git cat-file -p <blob-hash>git show <commit>cat .git/lost-found/other/<hash>Learn more
After recovery,
git cat-file -pandgit showlet you read the content of any recovered object. The.git/lost-found/other/directory (created bygit fsck --lost-found) contains hard links to all dangling blob objects, named by their SHA-1 hash. These files can be read directly withcatsince they are plain blobs (not the zlib-compressed loose object format —git fsckdecompresses them into lost-found).This challenge is a microcosm of real incident response: a threat actor attempted to destroy evidence by deleting a repository, the deletion was interrupted, and forensic investigators recover what they can from the surviving artifacts. The same skills — mounting disk images, using TSK, recovering git objects — are used in real forensic investigations of developer workstations, source code repositories, and cloud storage buckets.
Flag
picoCTF{...}
The repository was partially deleted. Surviving git objects or deleted inodes on the disk hold the flag. Use git fsck --lost-found and TSK icat to recover them.