Deleted File Recovery and Carving
Deleting a file removes its directory entry — not the data. File carving scans raw disk sectors for known file signatures and recovers the content even without filesystem metadata. This chapter covers NTFS undelete, file carving with Foremost/Scalpel, and Autopsy's carving capabilities.
An attacker ran a PowerShell script that collected system information, wrote the output to a file in a temp directory, compressed it with 7-Zip, and deleted both the script and the archive. The MFT has the deleted entry for both files (marked IsDeleted=True). The MFT record gives you the filename and timestamps — but not the content. The actual data clusters may still be on disk in the unallocated space. Foremost, running against the disk image, finds the 7-Zip archive by its signature (0x37 0x7A 0xBC 0xAF 0x27 0x1C — the 7z magic bytes) in unallocated clusters and recovers the content intact. Inside: the system information the attacker collected before exfiltrating it. This chapter explains how to do that.
How NTFS Deletion Works
NTFS File Deletion — What Actually Happens
═══════════════════════════════════════════════════════════════════
When Windows "deletes" a file:
1. MFT record marked as "not in use" (metadata preserved until reuse)
2. Directory entry removed (file no longer appears in listings)
3. $Bitmap entries for file's clusters cleared (clusters marked "free")
4. DATA content in the clusters: UNTOUCHED
→ The actual bytes remain on disk until overwritten
Recovery is possible as long as:
✓ MFT record not yet reused (metadata available)
✓ Data clusters not yet overwritten by new file data
→ Time between deletion and investigation matters:
Low-activity system: weeks to months of recovery window
High-activity system: hours to days
"Secure delete" tools:
Write random data over clusters before marking free
This destroys the content — carving finds zeroed/random sectors
Indicator: file clusters with all-zero or random byte patterns
where content would be expected = wiping was performed
SSD considerations:
TRIM command tells the SSD controller to erase blocks on deletion
Modern SSDs execute TRIM aggressively → very short recovery window
On SSDs, file carving recovery rates are much lower than on HDDs
Undelete with Autopsy
Autopsy shows deleted files with a red X icon in the file browser. These are MFT records where the "in use" flag is cleared — the metadata is still available.
Autopsy Deleted File Recovery Workflow
═══════════════════════════════════════════════════════════════════
1. Open disk image in Autopsy
2. In the tree: Data Sources → [image] → vol1 (NTFS)
3. Enable "Deleted Files" toggle in the file browser
→ Files with red X = deleted (MFT record available)
4. Right-click any deleted file → Extract File(s)
5. Autopsy reads the data clusters referenced by the MFT record
(if not overwritten) and saves the file to your analysis directory
6. Verify: compare file size in MFT record to recovered file size
→ Size mismatch = some clusters were overwritten (partial recovery)
Run the ingest module "File Type Identification" to:
- Detect file type mismatches (attacker renamed .exe as .txt)
- Identify files whose headers suggest content different from extension
File Carving with Foremost and Scalpel
File carving scans raw bytes for magic numbers (file type signatures) without relying on filesystem metadata. It recovers files even when the MFT records are gone.
# Foremost — file carving tool (available in SIFT)
# Scans raw disk image or unallocated space for known file signatures
# Carve all supported file types from a disk image
foremost -v \
-i /cases/CASE001/raw/HOST-srvr01.dd \
-o /cases/CASE001/carved/
# -v: verbose output (shows progress)
# -i: input image
# -o: output directory (one subdirectory per file type)
# Carve only specific types (-t flag)
foremost -v \
-t zip,pdf,doc,docx,xls,xlsx,7z,exe,jpg,png \
-i /cases/CASE001/raw/HOST-srvr01.dd \
-o /cases/CASE001/carved-specific/
# Foremost file type support (commonly useful types):
# zip, 7z, rar, gz — archives (attacker staging)
# doc, docx, xls, xlsx — Office documents
# pdf — PDFs
# exe, dll — executables
# jpg, png, gif — images (sometimes carries steganography)
# mov, avi, mp4 — video (rare but possible for evidence)
# Output structure:
# /carved/
# ├── audit.txt — carving log with offsets found
# ├── zip/ — recovered ZIP files
# │ ├── 00000001.zip
# │ └── ...
# └── exe/
# └── ...
# Scalpel — more configurable carving tool
# Allows custom file type definitions with regex-style header/footer patterns
# Edit /etc/scalpel/scalpel.conf to enable desired file types
# Uncomment lines for types you want to carve
# Run Scalpel
scalpel -c /etc/scalpel/scalpel.conf \
-o /cases/CASE001/scalpel-output/ \
/cases/CASE001/raw/HOST-srvr01.dd
# For carving only unallocated space (faster — skips allocated files):
# First extract unallocated space with blkls (TSK)
blkls -e /cases/CASE001/raw/HOST-srvr01.dd 2 > /cases/CASE001/unalloc.dd
# Then carve only from unallocated:
foremost -i /cases/CASE001/unalloc.dd -o /cases/CASE001/carved-unalloc/
Recycle Bin Forensics
When a user deletes a file via File Explorer (as opposed to Shift+Delete), it goes to the Recycle Bin first. The Recycle Bin stores the original file and metadata in a per-user directory.
Recycle Bin Structure (Windows Vista+)
═══════════════════════════════════════════════════════════════════
Location: C:\$Recycle.Bin\{User-SID}\
For each deleted file, two items are created:
$I{random6}.{ext} — metadata file (JSON-like binary):
original file path, deletion timestamp, file size
$R{random6}.{ext} — actual file content (the deleted file itself)
Both $I and $R share the same 6-character random suffix,
so $I{ABCDEF}.zip and $R{ABCDEF}.zip are a pair.
The $I file tells you:
- When exactly was the file deleted
- What its original path was (even if it was on a USB drive)
- Its original filename and size
The $R file lets you:
- Recover the deleted file content directly
# Parse Recycle Bin $I files to get deletion metadata
# $I files contain: file header + deletion time (FILETIME) + original path
param([string]$RecyclePath = "D:\evidence\C\`$Recycle.Bin")
Get-ChildItem $RecyclePath -Recurse -Filter '$I*' | ForEach-Object {
$iFile = $_
# Read binary data from $I file
$bytes = [System.IO.File]::ReadAllBytes($iFile.FullName)
if ($bytes.Length -lt 28) { return }
# Bytes 8-15: deletion timestamp (FILETIME — 8 bytes little-endian)
$fileTime = [BitConverter]::ToInt64($bytes, 8)
$deleteTime = [DateTime]::FromFileTimeUtc($fileTime)
# Bytes 16-23: original file size (8 bytes)
$fileSize = [BitConverter]::ToInt64($bytes, 16)
# Bytes 24+: original file path (UTF-16LE, null-terminated)
$pathBytes = $bytes[24..($bytes.Length - 1)]
$originalPath = [System.Text.Encoding]::Unicode.GetString($pathBytes).TrimEnd("`0")
# Find corresponding $R file
$rFileName = $iFile.Name -replace '^\$I', '$R'
$rFile = Join-Path $iFile.DirectoryName $rFileName
$contentAvailable = Test-Path $rFile
[PSCustomObject]@{
DeletedAt = $deleteTime
OriginalPath = $originalPath
FileSize = $fileSize
UserSID = ($iFile.DirectoryName -split "\\")[-1]
ContentFile = if ($contentAvailable) { $rFile } else { "MISSING" }
}
} | Sort-Object DeletedAt | Format-Table -AutoSize
Q & A
Q: File carving recovered hundreds of files. How do you prioritize which to analyze?
Prioritize by: (1) Type and size correlation — a 3.2 GB 7-Zip archive recovered from unallocated space in the investigation timeframe is high priority. A recovered JPEG thumbnail is not. (2) Time proximity to the incident — if you know the attacker was active on September 15, recovered files whose disk sector location corresponds to clusters written around that time (from the $LogFile journal) are more relevant. (3) Cross-reference with MFT — for MFT-based recovery (deleted file entry visible), you have the original filename and timestamps. Prioritize by matching to known-suspicious filenames from your artifact analysis. (4) File type relevance — focus on executables (.exe, .dll, .ps1), archives (.zip, .7z), and documents that could be exfiltration targets before personal photos and music files. (5) Hash lookup — hash every recovered executable and run against VirusTotal. A malicious hit is immediate high priority.