[{"content":"There\u0026rsquo;s a difference between recovering a file and producing evidence a court will accept, and the gap between the two is an entire discipline.\nIn my computer-forensics coursework at NFSU, one exercise drove that home. The task wasn\u0026rsquo;t \u0026ldquo;undelete the file.\u0026rdquo; It was: here is a disk image — examine it, and write your findings as a formal examination report in the format an Indian court accepts under Section 79A of the IT Act and Section 293 of the CrPC. Letterhead, chain of custody, exhibit marking, the works. That constraint changes how you work. You can\u0026rsquo;t lean on a GUI that says \u0026ldquo;6 files\u0026rdquo; if you can\u0026rsquo;t explain why it says 6. Every number has to trace back to a byte on the disk, and anyone with the same image has to be able to reproduce it.\nHere\u0026rsquo;s that investigation — the recovery, the four files caught lying about what they were, and why the byte-level discipline is the whole point.\nThe evidence One exhibit: a 15 GB forensic image of a USB flash drive, FAT32 (MD5 509dd658…). The questions were open-ended — how many files and directories, are any hidden, are any deleted, do the file types actually match their extensions, and has anything been tampered with. No hints about what I\u0026rsquo;d find.\nEverything below came from The Sleuth Kit (fls, istat, icat) plus xxd and dd — examined from the boot record through the FAT32 directory entries by hand.\nGround truth, byte by byte FAT32 stores every file and directory as one or more 32-byte directory entries. The first byte tells you the state — 0x00 ends the directory, 0xE5 marks a deleted entry, anything else is live — and the attribute byte at offset 0x0B separates directories (0x10) from files (0x20). Long names get extra entries (attribute 0x0F) stacked in front of the classic 8.3 entry.\nCounting straight from those entries: 3 directories, 12 active files, 1 deleted file. And here\u0026rsquo;s the first reason \u0026ldquo;court-admissible\u0026rdquo; forces byte-level work — a GUI tool like Autopsy reports 6 directories, because it counts its own virtual constructs ($OrphanFiles, $CarvedFiles, $Unalloc) that have no directory entry, no cluster, no existence on the physical disk. If your report says \u0026ldquo;6\u0026rdquo; because the tool said so, you lose the instant opposing counsel asks you to point to the sixth directory on the medium. The defensible answer is 3, and you can show every one.\nThe deleted file fls -r -d lists only entries flagged deleted. Exactly one came back: Lion King 5.jpg, inode 18. Deleting a file in FAT32 doesn\u0026rsquo;t erase anything — the OS just writes 0xE5 over the first byte of each directory entry and frees the cluster chain. The data sits untouched until something overwrites it.\nSo I dumped the raw directory cluster and read the deleted entry by hand:\nThree consecutive entries, each beginning with e5: two Long File Name fragments and the 8.3 record. Read the LFN fragments bottom-up — Lion King 5.j + pg — and the original name reconstructs to Lion King 5.jpg. The 8.3 entry still holds the starting cluster (1810) and size (165,264 bytes), and the FAT showed those clusters were never reallocated.\nSo recovery isn\u0026rsquo;t a gamble here. icat pulls the bytes straight from the cluster chain — and the recovered file has to prove it\u0026rsquo;s intact, which it does, in its own header:\nFF D8 FF E1 — the JPEG Start-of-Image and Exif markers. A 165 KB file the filesystem had marked \u0026ldquo;deleted,\u0026rdquo; recovered and verified as a genuine, complete image. In a report that distinction is everything: I didn\u0026rsquo;t just get a file back, I demonstrated the recovered bytes are authentic.\nFiles in disguise This is where it got interesting. An extension is just a label a user types; the magic bytes at the start of a file are the truth. Checking every file\u0026rsquo;s signature against its extension turned up four that were lying.\nAn MP3 that\u0026rsquo;s a video. Sample Image.mp3 should open with an MPEG frame-sync (FF FB) or an ID3 tag. Instead:\n…ftypmp42 — the ISO Base Media ftyp box. It\u0026rsquo;s an MP4 video wearing an .mp3 extension.\nA spreadsheet older than it claims. file_example.xlsx should be a ZIP (50 4B 03 04 — .xlsx is zipped XML). Instead it\u0026rsquo;s an OLE2 compound document — the legacy .xls format — and the OLE2 header even carries an embedded creation date:\nCreated August 2017. The extension was changed to look modern; the bytes remember when the file was really made. That\u0026rsquo;s a provenance tell you\u0026rsquo;d never get from a directory listing.\nA Word document that\u0026rsquo;s audio. The most blatant one — file_example.docx. You don\u0026rsquo;t even need a tool; the ASCII column says it out loud:\nRIFF….WAVEfmt — a CD-quality WAV audio file renamed to .docx. The chunk-size field even matches the on-disk file size exactly, proving it\u0026rsquo;s complete and untruncated, just mislabeled.\n(The fourth, File Sample.doc, was subtler: a modern .docx — ZIP/PK — stored under the legacy .doc extension. Wrong label, right family.)\nThe quiet tell One more, easy to miss. Lion King 4.jpg\u0026rsquo;s metadata showed a Written time earlier than its Created time:\nIn a normal \u0026ldquo;create a new file\u0026rdquo; flow that\u0026rsquo;s impossible — you can\u0026rsquo;t modify something before it exists. What it actually means: the file was copied onto this volume from somewhere else, and FAT32 kept the original modification time while stamping a fresh creation time at copy. Another provenance breadcrumb, sitting in plain sight in the directory entry.\nWhy \u0026ldquo;court-admissible\u0026rdquo; is the whole point None of the individual techniques here are exotic — fls, a hex dump, a magic-byte check. What makes it forensics rather than tinkering is that every claim is anchored to a byte and reproducible by anyone with the image: 3 directories (not the tool\u0026rsquo;s 6), a recovered JPEG verified by its own header, four extensions disproven by their signatures, a copied file betrayed by its timestamps. No \u0026ldquo;the tool said so.\u0026rdquo;\nThat\u0026rsquo;s the line between I recovered a file and evidence that survives cross-examination — and learning to work on the right side of it, in the report format a court actually expects, was the real exercise.\n","permalink":"https://kartiksankhla.com/posts/court-admissible-fat32/","summary":"A FAT32 USB image examined the way a court requires — no GUI shortcuts, every claim tied to raw bytes: recovering a deleted JPEG, and catching four files wearing the wrong extension.","title":"A court-admissible FAT32 investigation, byte by byte"},{"content":"During a five-day filesystem-forensics bootcamp at NFSU, I was given a forensic image of a Linux pen drive and a one-line task: do forensics on it. No scenario, no hints, no list of what to look for — just the image. Everything below, I had to work out on my own.\nWhat I pieced together: a user had created five text files, 1.txt through 5.txt, and deleted some of them. Four came back. One — 5.txt — was gone, and the interesting part was proving why. Along the way the filesystem handed me something nobody had asked for: a near minute-by-minute record of what the user had actually been doing. Here\u0026rsquo;s the whole thing, dead ends included.\nFirst, the wrong way (and why I\u0026rsquo;m showing it) Most forensics writeups show only the clean path. The detours taught me more, so they stay in.\nMy first instinct was to carve — scan the raw bytes for file signatures and pull out anything shaped like a JPEG:\ngrep -boa $\u0026#39;\\xff\\xd8\\xff\u0026#39; Sample_03.E01 That failed instantly, for an instructive reason: the image was an E01 (EnCase) container, which is compressed. Byte offsets into it point at compressed data, not real disk sectors. So I exported a raw .dd and tried again — and promptly \u0026ldquo;recovered\u0026rdquo; a wallpaper that had never been deleted. Blind carving across a whole disk happily hands you files that are still alive. A dedicated free-space carver did better (208 JPEG candidates, exactly one valid) but missed the artifacts that mattered, because they weren\u0026rsquo;t in free space at all.\nThe pivot was to stop guessing and ask the filesystem what should be here before hunting for what\u0026rsquo;s missing:\nfls -r -o 2048 -m / pendrive.dd That one command — a recursive listing that includes deleted entries — reframed the entire case.\nReconnaissance: the filesystem tells on itself mmls put the Linux partition at sector offset 2048 (the standard 1 MiB alignment). fsstat identified it:\nFile System Type: Ext3 Block Size: 4096 Block Groups: 112 ... Orphan inodes: 319100, 319081 That last line is the kind of gift you don\u0026rsquo;t ignore. Orphan inodes are allocated inodes with zero directory links — typically a file deleted while still open, or an unclean unmount. The superblock was pointing straight at two of them before I\u0026rsquo;d recovered anything. Hold that thought.\nA look under /home/dora/ showed the usual GNOME layout: Desktop, Documents, .cache, and .local/share/Trash. (It was only later that the username clicked — dora — and I realized the disk had been built for the exercise, not seized from anyone real.)\nThe easy wins: Trash On a Linux desktop, \u0026ldquo;deleting\u0026rdquo; a file in the file manager doesn\u0026rsquo;t rm it — it moves it into ~/.local/share/Trash/, which keeps two things: the content under files/, and a small .trashinfo record under info/:\nicat -o 2048 pendrive.dd 319089 [Trash Info] Path=/home/dora/Desktop/4.txt DeletionDate=2026-02-08T23:55:41 There\u0026rsquo;s the original path and the exact deletion time, handed to me for free. The Trash held 2.txt and 4.txt, both recovered intact. Active files 1.txt and 3.txt had never been deleted at all.\nThat left 5.txt — and it was nowhere in the Trash. Which already said something: it hadn\u0026rsquo;t been deleted through the GUI. It had been rm\u0026rsquo;d, bypassing Trash entirely.\nThe orphan inodes: a behavioral goldmine Back to the two orphans fsstat flagged. I pulled inode 319100 (32 KiB, link count 0) and ran it through xxd:\nistat -o 2048 pendrive.dd 319100 xxd orphan_319100.bin | head ... 6a 6f 75 72 → \u0026#34;jour\u0026#34; (journal) /Desktop/3.txt /Desktop/4.txt gedit-position This wasn\u0026rsquo;t user data — it was a GEdit session journal, a GVFS metadata file. It recorded which files had been open in the text editor (3.txt and 4.txt) and even the cursor position (offset 14, near the end of a 15-byte file). The second orphan, inode 319081, was Nautilus metadata — desktop icon positions and file-manager state:\nstrings orphan_319081.bin | grep -E \u0026#34;txt|Trash\u0026#34; Folder 4.txt 3.txt Trash 2.txt 1.txt This is the part I think is genuinely underrated. A filesystem timestamp tells you a file was touched; this desktop-environment metadata tells you what the person did — which files they opened versus merely created, how the desktop was arranged, what sat in the Trash. And one thing stood out by its absence: 5.txt appears nowhere in it. It was never opened in the editor. Created, and deleted, without ever being read.\nWhy 5.txt was gone for good The headline mystery. fls -d (deleted entries only) showed 5.txt pointing at inode 319070, flagged realloc:\nr/r * 319070(realloc): 5.txt But pulling that inode\u0026rsquo;s content gave the wrong answer:\nicat -o 2048 pendrive.dd 319070 \u0026#34;This is file 1\u0026#34; That\u0026rsquo;s not 5.txt\u0026rsquo;s content — that\u0026rsquo;s 4.txt\u0026rsquo;s. The realloc flag is the tell: after 5.txt was deleted and its inode freed, inode 319070 was reused by 4.txt. The metadata slot now describes a completely different file. And the data blocks? One last check:\ngrep -abo \u0026#34;This is file 5\u0026#34; pendrive.dd # (no matches) Nothing. The content had been overwritten too. 5.txt wasn\u0026rsquo;t hidden or corrupted — it was genuinely, permanently destroyed.\nPutting time back together Stitching inode MAC times together with the GVFS metadata timestamps reconstructed a roughly eight-minute session:\nTime (IST) Event 23:52:06 3.txt created 23:53:41 4.txt opened in gedit 23:55:40 5.txt created (inode 319070) 23:55:41 2.txt moved to Trash 23:56:33 5.txt deleted (inode freed) 00:00:35 inode 319070 reused by 4.txt 5.txt existed for 53 seconds, and its inode was recycled about four minutes later. Recovery was a race it had already lost.\nWhat I took away Deletion is not destruction — until the inode is reused or the blocks are overwritten. Recovery is a race against system activity, and sometimes you lose it — which is itself a defensible, documentable finding. Ask the filesystem what should exist before you carve. Filesystem-aware analysis beat blind carving at every step; blind carving actively misled me with files that were never deleted. Orphan inodes and desktop-environment metadata are evidence. The GEdit journal and Nautilus state reconstructed user behavior, not just file contents — and 5.txt\u0026rsquo;s absence from them was as informative as the files I recovered. Keep your dead ends. The failed carving attempts are exactly what taught me which kind of evidence I was actually looking for. The tooling is all The Sleuth Kit — mmls, fsstat, fls, istat, icat — plus xxd and grep. None of it is exotic. The investigation lived in the order you ask the questions.\n","permalink":"https://kartiksankhla.com/posts/the-file-we-couldnt-recover/","summary":"A user created five files and deleted some. Recovering them from an ext3 image meant Trash artifacts, orphan inodes full of GNOME metadata — and proving why one file was gone for good.","title":"The file we couldn't recover: an ext3 deleted-file investigation"},{"content":"I\u0026rsquo;m setting this site up as a place to write about digital forensics and the low-level Linux work I spend most of my time on — memory and filesystem forensics, malware analysis, and the occasional thing I build along the way.\nMore to come. If you want to see what I\u0026rsquo;m working on in the meantime, my code is on GitHub.\n","permalink":"https://kartiksankhla.com/posts/hello/","summary":"A short note on what I\u0026rsquo;ll be writing about here.","title":"Hello, and what this site is"},{"content":"I\u0026rsquo;m Kartik Sankhla — a digital-forensics and Linux security researcher, currently doing an M.Tech in Cyber Security at the National Forensic Sciences University (NFSU), Gandhinagar.\nMy focus is DFIR: digital forensics and incident response. I work across memory forensics, filesystem forensics (ext4/XFS/Btrfs/FAT32), malware analysis and reverse engineering, Android security, and the OT/ICS side of critical-infrastructure security. I\u0026rsquo;ve used Linux as my daily driver for over a decade, and most of my work lives close to the operating system.\nMost of my research is hands-on Linux forensics: designing controlled, reproducible experiments to understand how systems behave under investigation, and building the tooling to support that analysis. Some of this work is currently under submission to a peer-reviewed venue — I\u0026rsquo;ll write more about it here once it\u0026rsquo;s published.\nI also led the architecture for a Government-of-India 5G disaster-response hackathon proposal (RAKSHAK-NTN), which was shortlisted at the national level.\nThis site is where I write up what I\u0026rsquo;m investigating and building.\nGitHub: github.com/kartik0025 LinkedIn: linkedin.com/in/kartik0025 Email: kartik0025@gmail.com ","permalink":"https://kartiksankhla.com/about/","summary":"About Kartik Sankhla","title":"About"}]