Perform a full disk forensic investigation using Autopsy, The Sleuth Kit, and Plaso/log2timeline on SIFT Workstation. Acquire forensic images, reconstruct attacker activity through NTFS artifacts, build a super-timeline, and produce a court-ready forensic report.
On SIFT Workstation (192.168.56.20), create a bit-for-bit forensic image of the evidence drive:
sudo apt install -y dcfldd autopsy sleuthkit mkdir ~/disk-lab && cd ~/disk-lab # Identify evidence disk (use lsblk first) lsblk -o NAME,SIZE,TYPE,MOUNTPOINT sudo fdisk -l # Create forensic image with hash verification # Replace /dev/sdb with your evidence disk (NEVER the live system disk) sudo dcfldd if=/dev/sdb \ of=~/disk-lab/evidence.dd \ bs=512 \ hash=md5,sha256 \ hashlog=~/disk-lab/evidence_hashes.txt \ errlog=~/disk-lab/evidence_errors.txt \ statusinterval=256 # Alternatively, use dd with hash verification sudo dd if=/dev/sdb bs=4M conv=sync,noerror status=progress | \ tee evidence.dd | md5sum > evidence_md5.txt echo "Hash verification:" cat evidence_hashes.txt
For lab practice without a real disk:
# Download a pre-made forensic image for practice # NIST CFReDS (Computer Forensics Reference Data Sets) wget -O ~/disk-lab/evidence.dd.gz \ "https://cfreds.nist.gov/all/NIST/HackingCase" 2>/dev/null || \ echo "Visit cfreds.nist.gov to download practice disk images" # Alternative: Create a small test image dd if=/dev/urandom of=~/disk-lab/test.dd bs=1M count=512 mkfs.ntfs ~/disk-lab/test.dd # Format as NTFS for practice
# Verify MD5/SHA256 hash matches original md5sum ~/disk-lab/evidence.dd sha256sum ~/disk-lab/evidence.dd # Document in chain of custody echo "Evidence: evidence.dd" >> ~/disk-lab/chain_of_custody.txt echo "MD5: $(md5sum ~/disk-lab/evidence.dd | cut -d' ' -f1)" >> ~/disk-lab/chain_of_custody.txt echo "SHA256: $(sha256sum ~/disk-lab/evidence.dd | cut -d' ' -f1)" >> ~/disk-lab/chain_of_custody.txt echo "Analyst: $(whoami)" >> ~/disk-lab/chain_of_custody.txt echo "Date: $(date -u)" >> ~/disk-lab/chain_of_custody.txt # Mount read-only using loop device mkdir -p ~/disk-lab/mount sudo losetup -r -f ~/disk-lab/evidence.dd LOOP=$(sudo losetup -j ~/disk-lab/evidence.dd | cut -d: -f1) echo "Loop device: $LOOP" # Mount NTFS partition read-only (adjust partition offset as needed) sudo mmls ~/disk-lab/evidence.dd # Show partition table # Mount primary partition (find offset from mmls output) sudo mount -o ro,loop,offset=$((63*512)) ~/disk-lab/evidence.dd ~/disk-lab/mount/ ls ~/disk-lab/mount/
Launch Autopsy and set up the forensic case:
# Launch Autopsy (web-based interface on SIFT) autopsy & # Navigate to http://localhost:9999/autopsy in browser # Or use Autopsy 4 (GUI) # If not installed: wget https://github.com/sleuthkit/autopsy/releases/latest
In Autopsy:
L14_DiskForensics, Case Type: Single-userevidence.dd# Alternatively: command-line with The Sleuth Kit # List files in NTFS image fls -r ~/disk-lab/evidence.dd > ~/disk-lab/file_listing.txt echo "Files listed: $(wc -l < ~/disk-lab/file_listing.txt)" # Extract deleted files fls -r -d ~/disk-lab/evidence.dd | head -50 # Get file system metadata fsstat ~/disk-lab/evidence.dd
NTFS metadata files contain rich forensic evidence about file activity:
# Parse $MFT (Master File Table) — every file's metadata pip3 install analyzeMFT analyzeMFT.py -f ~/disk-lab/mount/\$MFT -o ~/disk-lab/mft_analysis.csv echo "MFT entries: $(wc -l < ~/disk-lab/mft_analysis.csv)" # Parse $UsnJrnl (change journal) — all file changes icat ~/disk-lab/evidence.dd 2 0 > ~/disk-lab/usnjrnl_raw.bin 2>/dev/null || \ echo "Extract UsnJrnl via Autopsy" # Use TSK to get timestamps for specific files istat ~/disk-lab/evidence.dd [inode_number] # List recently modified files (last 30 days — adjust for investigation timeframe) mactime -b ~/disk-lab/mft_analysis.csv \ -d 2024-01-01 -e 2024-03-01 > ~/disk-lab/timeline_mft.txt echo "Files with activity in date range:" head -50 ~/disk-lab/timeline_mft.txt
Windows Registry hives contain persistence mechanisms, recently run programs, and network connections:
# Copy registry hives from mounted image
mkdir ~/disk-lab/registry
cp ~/disk-lab/mount/Windows/System32/config/{SYSTEM,SOFTWARE,SAM,SECURITY} \
~/disk-lab/registry/ 2>/dev/null
# Also grab user hives (NTUSER.DAT)
find ~/disk-lab/mount/Users -name "NTUSER.DAT" -exec cp {} ~/disk-lab/registry/ \; 2>/dev/null
# Parse with RegRipper
pip3 install python-registry
cat > ~/disk-lab/parse_registry.py << 'EOF'
from Registry import Registry
import sys
def parse_hive(path):
try:
reg = Registry.Registry(path)
return reg
except Exception as e:
print(f"Error: {e}")
return None
# Run/RunOnce keys (persistence)
def get_persistence(software_hive):
reg = parse_hive(software_hive)
if not reg: return
persistence_keys = [
"Microsoft\\Windows\\CurrentVersion\\Run",
"Microsoft\\Windows\\CurrentVersion\\RunOnce",
"Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
]
print("\n=== PERSISTENCE MECHANISMS ===")
for key_path in persistence_keys:
try:
key = reg.open(key_path)
print(f"\nHKLM\\{key_path}:")
for value in key.values():
print(f" {value.name()}: {value.value()}")
except Registry.RegistryKeyNotFoundException:
pass
get_persistence("registry/SOFTWARE")
EOF
python3 parse_registry.py
Plaso/log2timeline parses 200+ artifact types into a unified timeline:
# SIFT has Plaso pre-installed log2timeline.py --version # Create Plaso storage file (this takes time — 30-60min for large images) log2timeline.py \ --timezone UTC \ --parsers "win_registry,winprefetch,winevtx,recycle_bin,lnk,chrome_history" \ ~/disk-lab/evidence.plaso \ ~/disk-lab/evidence.dd echo "Timeline extraction complete" du -sh ~/disk-lab/evidence.plaso
# Export timeline to CSV for analysis
psort.py \
--output-time-zone UTC \
-o l2tcsv \
-w ~/disk-lab/super_timeline.csv \
~/disk-lab/evidence.plaso
echo "Timeline rows: $(wc -l < ~/disk-lab/super_timeline.csv)"
# Filter to incident timeframe (adjust dates)
python3 << 'EOF'
import pandas as pd
df = pd.read_csv('disk-lab/super_timeline.csv', low_memory=False)
print(f"Total events: {len(df)}")
print(f"Columns: {list(df.columns)}")
# Filter to key time window (when attack occurred)
# Adjust dates based on your investigation
df['datetime'] = pd.to_datetime(df.get('datetime', df.get('date', '')),
errors='coerce', utc=True)
df = df.dropna(subset=['datetime'])
start = pd.Timestamp('2024-03-01 08:00:00', tz='UTC')
end = pd.Timestamp('2024-03-01 12:00:00', tz='UTC')
attack_window = df[(df['datetime'] >= start) & (df['datetime'] <= end)]
print(f"\nEvents in attack window: {len(attack_window)}")
# Show most suspicious artifact types
print("\nArtifact types in window:")
print(attack_window.get('source', attack_window.get('sourcetype',
pd.Series())).value_counts().head(15))
attack_window.sort_values('datetime').to_csv(
'disk-lab/attack_window_timeline.csv', index=False)
print("Filtered timeline saved")
EOF
Prefetch files show what executables ran and when; LNK files show recently accessed files:
# Parse Prefetch files
pip3 install prefetch-parser
python3 << 'EOF'
import glob, subprocess
prefetch_dir = "disk-lab/mount/Windows/Prefetch"
import os
if os.path.exists(prefetch_dir):
files = glob.glob(f"{prefetch_dir}/*.pf")
print(f"Found {len(files)} Prefetch files")
for pf in sorted(files)[:20]:
# Use TSK or python-prefetch to parse
print(f" {os.path.basename(pf)}")
else:
print("Prefetch directory not found — may be disabled on this system")
print("Check: HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\PrefetchParameters")
print("EnablePrefetcher: 0=disabled, 2=app, 3=app+boot")
EOF
# Parse LNK files (show recently opened documents)
python3 << 'EOF'
import glob, os
lnk_dirs = [
"disk-lab/mount/Users/*/AppData/Roaming/Microsoft/Windows/Recent/*.lnk",
"disk-lab/mount/Users/*/Desktop/*.lnk",
]
for pattern in lnk_dirs:
for lnk in glob.glob(pattern):
print(f"LNK: {os.path.basename(lnk)}")
print("\nInstall python-lnk for detailed parsing:")
print("pip3 install python-lnk")
EOF
# List deleted files with TSK fls -r -d ~/disk-lab/evidence.dd | grep -i "\.(exe\|bat\|ps1\|vbs\|docx\|pdf\|zip)" \ | head -30 # Recover specific deleted file by inode number # (get inode from fls output — e.g., "r/r * 12345: deleted_file.exe") icat ~/disk-lab/evidence.dd 12345 > ~/disk-lab/recovered/recovered_file.exe sha256sum ~/disk-lab/recovered/recovered_file.exe # Bulk file carving with PhotoRec (recovers by file signatures, ignores FS) sudo apt install -y testdisk photorec /d ~/disk-lab/recovered ~/disk-lab/evidence.dd # Check recovered file types find ~/disk-lab/recovered -type f | xargs file | head -30 echo "Examine recovered executables with:" echo " file, strings, sha256sum against VirusTotal hashes"
# Chrome history (SQLite database)
pip3 install browser-history sqlite3
python3 << 'EOF'
import sqlite3, glob, shutil, os, tempfile
chrome_paths = glob.glob(
"disk-lab/mount/Users/*/AppData/Local/Google/Chrome/User Data/Default/History")
for history_path in chrome_paths:
user = history_path.split('/')[3]
# Copy to temp (Chrome locks original)
tmp = tempfile.mktemp(suffix='.db')
shutil.copy(history_path, tmp)
conn = sqlite3.connect(tmp)
cursor = conn.execute("""
SELECT datetime((last_visit_time/1000000-11644473600), 'unixepoch') as visit_time,
url, title, visit_count
FROM urls
WHERE last_visit_time > 0
ORDER BY last_visit_time DESC
LIMIT 100
""")
print(f"\n=== Chrome History: {user} ===")
for row in cursor.fetchall():
print(f" {row[0]} | {row[3]}x | {row[1][:80]}")
conn.close()
os.unlink(tmp)
EOF
Correlate all artifacts into a coherent attack narrative:
| Timestamp (UTC) | Artifact Type | Evidence | Significance |
|---|---|---|---|
Use the AI analyst to help structure your forensic report per SWGDE standards.
| Metric | Value |
|---|---|
| Evidence image hash (MD5) | |
| OS / File System | |
| Timeline events extracted | |
| Deleted files recovered | |
| Key persistence found | |
| Attack timeframe |