Skip to content

Latest commit

 

History

History
523 lines (411 loc) · 19.2 KB

forensics.md

File metadata and controls

523 lines (411 loc) · 19.2 KB

+

documentation, specification

malware family / classification

malware analysis / sandbox

event log

process information

/proc/self/cmdline
/proc/self/cwd/

memory analysis

memory dump

live system

# load driver
winpmem.exe -l
# run against raw device
vol.py -f \\.\pmem --profile Win7SP1x64 pslist

filesystem mounting

apt-get install xmount ewf-tools afflib-tools sleuthkit
pip3 install imagemounter
imount --check
# ||
sudo mount -t ext4 -o loop foo mnt_dir

filesystem timestamps

https://countuponsecurity.com/2016/05/30/digital-forensics-ntfs-indx-and-journaling/

recovering files

# list deleted files with filesystem start offset
fls -o 129 foo.dd

# recover all files
tsk_recover -o 129 foo.dd .
# || recover files, by inode
# Reference: [How To Search for Strings on a Disk Image Using The Sleuth Kit \- LMG Security](https://www.lmgsecurity.com/sleuth-kit/)
icat -o 129 -r foo.dd 54
# recover all files from journal
extundelete artefact --restore-all

# list deleted files, with full paths, recursively
fls -d -p -r /dev/sda
# recover files, from unallocated space (carving), by extension
sed -i 's/^#[[:space:]]\+\(\(doc\|pdf\|gif\|jpg\|png\).*\)/\1/g' /etc/scalpel/scalpel.conf
scalpel /dev/sda

ignore likely carved false positives

find . -type f -name '*.png' -size +1500k -delete
find . -type d -empty -delete

carving with dd

dd if=/proc/7/mem bs=$((0x1000)) skip=$((Ox7fb84ee44 + 0x207)) count=1 of=out

windows

  1. create disk image
    # List disks
    wmic diskdrive list
    # ||
    Get-WmiObject Win32_DiskDrive
    # Dump disk
    dd.exe if=\\.\PhysicalDrive0 of=d:\images\PhysicalDrive0.img --md5sum --verifymd5 --md5out=d:\images\PhysicalDrive0.img.md5
  2. carving

data sets

pdf

# disable security / drm / no copy restriction bits
qpdf --decrypt input.pdf out.pdf
pdftk input.pdf output out.pdf allow AllFeatures
gs -sPDFPassword=$PASS -q -dNOPAUSE -dBATCH -dSAFER -r300 -sDEVICE=pdfwrite -sOutputFile=%stdout% -c .setpdfwrite -f input.pdf > output.pdf

# decompress streams
qpdf --qdf --object-streams=disable foo.pdf foo.decompressed.pdf

# edit
qpdf -qdf --stream-data=uncompress foo.pdf foo.decompressed.pdf
# [...]
mutool clean

# enumerate references
f=challenge.pdf && { \
  peepdf "$f" | \
  grep 'Objects ([0-9]*):' | \
  sed 's/.*\[\(.*\)\]/\1/; s/\([0-9]\+\)\(, \)\?/references to \1\n/g' | \
  peepdf "$f" -i
} 2>/dev/null

zlib

  • compression level magic bytes
    • 78 01: None / Low
    • 78 9C: Default (Common)
    • 78 DA: Best

zip

# Fix
zip -F foo.zip --out foo.fixed.zip
zip -FF foo.zip --out foo.fixed.zip

# Extract broken zip
bsdtar xf zipfile

# Extract multipart archive
# Given: archives ordered by name
cat foo.*.zip > foo.zip
zip -FF foo.zip --out foo.fixed.zip

# bruteforce password
while read -r i; do 7z x -p"$i" flag.zip >/dev/null; e=$?; if [ ! -s flag.txt ] || [ $e -gt 0 ]; then rm flag.txt; else break; fi; done < ~/code/guides/ctf/SecLists/Passwords/Leaked-Databases/rockyou-75.txt
# preserve attempts where CRC Failed
while read -r i; do 7z x -p"$i" flag.zip >/dev/null; if [ ! -s flag.txt ]; then rm flag.txt; else mv flag.txt flags/"$(date +%s)".flag.txt; fi; done < ~/code/guides/ctf/SecLists/Passwords/Leaked-Databases/rockyou-75.txt

extraction path

encryption / password attacks

Bruteforce:

~/opt/john/run/zip2john flag.zip > flag.zip.john
~/opt/john/run/john --wordlist="$(realpath ~/share/opt/rockyou.txt)" flag.zip.john

Biham and Kocher's known plaintext attack:

7-Zip

rar

# Extract broken rar
unrar e -kb

# Extract multipart archive
# Given: archives ordered by name
unrar x foo.part1.rar

steganography

printers, yellow dots, machine identification code

file formats

diff

datasets

polyglots

Detection / Parsing:

file -k _
binwalk --dd='.*' _
binwalk -Me _
# alternatives:
# - [unblob](https://unblob.org/formats/): splits unknown chunks from archive / fs
# - [OFRAK](https://ofrak.com/): allows manipulates / repacks
# - [GitHub \- fkie\-cad/FACT\_core: Firmware Analysis and Comparison Tool](https://github.com/fkie-cad/FACT_core)

# graphics images
exiftool -v _
identify -verbose _
python3 -c 'import cv2, sys; cv2.imread(sys.argv[1])' _
python3 -c 'import sys; from PIL import Image; print(Image.open(sys.argv[1]).verify())' _
pngcheck -f -vv _

# pdfs
pdfinfo _
qpdf --check _
caradoc stats _

# disk images
### files
fls _
### metadata
iat --debug -i _
ksv ~/opt/isolyzer/testFiles/iso9660.iso ~/opt/kaitai_struct/formats/filesystem/iso9660.ksy
### verify expected file size extracted from headers consistent with actual size
isolyzer _

# archives
7z t _

No magic enforced at offset zero:

  • PDF, PostScript, BMFF (mp4, mov, heic...), DICOM (medical images), TAR, ZIP, Rar, 7z, Arj, raw dumps (.iso, roms)

Examples:

Parasites:

hash collisions

mocks

invalid data

# identify by chunks vs. magic bytes
### png
hexgrep.py _ "$(printf '%s' 'PNG|IHDR|PLTE|IDAT|IEND' | xxd -p)"
grep -Habo $'PNG\\|IHDR\\|PLTE\\|IDAT\\|IEND' _
file -k * | grep '\s*data' | cut -d':' -f1 | xargs -i env LC_ALL=C awk 'match($0, /PNG|IHDR|PLTE|IDAT|IEND/) {
    offset = count + RSTART - 1;
    group = substr($0, RSTART, RLENGTH);
    printf("%s:%s(0x%x):%s\n", FILENAME, offset, offset, group);
} { count += length + 1; }' {}
### jpeg
hexgrep.py _ '\xff\xd8|\xff\xe0|JFIF|\xff\xdb|\xff\xc0|\xff\xc4|\xff\xda|\xff\xd9'
grep -Habo $'\xff\xd8\\|\xff\xe0\\|JFIF\\|\xff\xdb\\|\xff\xc0\\|\xff\xc4\\|\xff\xda\\|\xff\xd9' _
file -k * | grep '\s*data' | cut -d':' -f1 | xargs -i env LC_ALL=C awk 'match($0, /\xff\xd8|\xff\xe0|JFIF|\xff\xdb|\xff\xc0|\xff\xc4|\xff\xda|\xff\xd9/) {
    offset = count + RSTART - 1;
    group = substr($0, RSTART, RLENGTH);
    printf("%s:%s(0x%x):%s\n", FILENAME, offset, offset, group);
} { count += length + 1; }' {}

NAND storage

case studies

zeroing section headers to thwart dissassemblers

  • windows
    • GetModuleHandle
    • VirtualProtect + RtlZeroMemory
  • linux
    • fopen("/proc/self/maps", "r")
    • fscanf addresses
    • mprotect + memset
winpmem-2.1.post4.exe -o lol.aff4
"C:\Program Files\Rekall\rekal.exe" -f lol.aff4
# procdump proc_regex="thekeys", dump_dir="C:/Users/int0x80/Desktop/"
git clone https://github.com/504ensicsLabs/LiME
sudo insmod ./lime-$(uname -r).ko "path=/tmp/1"

git clone https://github.com/volatilityfoundation/volatility
# Build profile for current machine
cd ~/tools/volatility/tools/linux/
make
# Validation
grep '.debug_info' module.dwarf

python vol.py -f /tmp/1 --profile=Linux...
# linux_pslist
# linux_procdump