strings & File Triage
Before a disassembler, before a sandbox, there is the ten-minute pass every unknown file gets: what is it really (file, magic bytes), what is written inside it (strings, in the right encoding), what does it carry (exiftool, binwalk, embedded objects), what does it match (hashes, ssdeep, YARA). The same tools, pointed at a memory image, a swap file or the unallocated blocks of a disk, become carving — pulling files and indicators out of space no filesystem points to. This card is those tools, Linux/macOS first with the Windows equivalent next to each, and the patterns that make strings output readable instead of a 40,000-line wall.
[!warning] Handle malware like malware Work on a copy, in a VM with no shared clipboard or network, with the file renamed to
sample.binso nothing double-clicks it.strings,fileandexiftooldo not execute anything — butbinwalk -e,7z xand PDF tools that render can trigger parser bugs. Snapshot first.
Identify: what is it really?
file sample.bin # libmagic: type, arch, linker, packer hints
file -b --mime-type sample.bin # bare MIME
file -z archive.gz # look inside compressed
file -k sample.bin # keep going, report all matches (polyglots)
file * # a whole directory, quickly
xxd sample.bin | head -4 # eyeball the magic yourself
# Windows: no `file`, so read the magic
Format-Hex .\sample.bin -Count 32
certutil -dump .\sample.bin | Select -First 5 # for certs/PKCS
# or install: winget install GnuWin32.File / use TrID (trid.exe sample.bin)
| Magic (hex) | ASCII | Type |
|---|---|---|
4D 5A | MZ | Windows PE (exe/dll/sys) — PE\0\0 follows at offset in 0x3C |
7F 45 4C 46 | .ELF | Linux/Unix executable |
CF FA ED FE / CA FE BA BE | Mach-O 64-bit / universal (fat) | |
50 4B 03 04 | PK.. | ZIP — also docx/xlsx/pptx, jar, apk, ipa, odt |
D0 CF 11 E0 A1 B1 1A E1 | OLE2 / CFB — legacy doc/xls/ppt, msi, msg | |
25 50 44 46 | %PDF | |
7B 5C 72 74 66 | {\rtf | RTF (CVE-2017-11882 territory) |
1F 8B | gzip | |
42 5A 68 | BZh | bzip2 |
FD 37 7A 58 5A 00 | .7zXZ. | xz |
37 7A BC AF 27 1C | 7z..'. | 7-Zip |
52 61 72 21 1A 07 | Rar!.. | RAR |
75 73 74 61 72 @257 | ustar | tar |
FF D8 FF | JPEG | |
89 50 4E 47 0D 0A 1A 0A | .PNG | PNG |
47 49 46 38 | GIF8 | GIF |
52 49 46 46 | RIFF | WAV/AVI/WebP |
53 51 4C 69 74 65 | SQLite | SQLite DB (browser history, Windows Timeline, mobile apps) |
72 65 67 66 | regf | Windows registry hive |
45 6C 66 46 69 6C 65 | ElfFile | Windows EVTX |
4C 00 00 00 01 14 02 00 | L... | Windows LNK |
4D 41 4D 04 / 53 43 43 41 @4 | MAM. / SCCA | Prefetch (compressed Win10 / raw) |
EF BB BF / FF FE / FE FF | UTF-8 BOM / UTF-16 LE / BE text | |
23 21 | #! | script with shebang |
4D 53 43 46 | MSCF | CAB |
43 57 53 / 46 57 53 | CWS/FWS | Flash |
00 00 00 xx 66 74 79 70 | ftyp @4 | MP4/MOV/HEIC |
4B 44 4D | KDM | VMware VMDK |
63 6F 6E 65 63 74 69 78 | conectix | VHD |
45 56 46 09 0D 0A FF 00 | EVF | EnCase E01 |
4C 69 4D 45 | LiME | LiME memory dump |
[!tip] Extension lies, magic mostly doesn’t
invoice.pdf.exe,report.docmrenamed to.doc, a JPEG with a PHP webshell appended (filesays JPEG,stringssays<?php), a ZIP that is also a valid PDF.file -kand looking at both ends of the file (xxd | head,xxd | tail) catch most polyglots and appended payloads. Trailing data after the PNGIENDchunk or after the ZIP central directory is never innocent.
strings in depth
GNU strings (binutils) prints runs of printable characters ≥ 4 bytes. The defaults hide half of what a Windows binary contains.
strings sample.bin # ASCII (and single-byte) runs ≥ 4 chars
strings -n 8 sample.bin # minimum length 8 — cuts the noise dramatically
strings -a sample.bin # -a: scan the WHOLE file, not just loaded sections (default on modern binutils, be explicit)
strings -e l sample.bin # 16-bit little-endian = UTF-16LE: Windows API strings, paths, registry keys, PowerShell in .NET binaries
strings -e b sample.bin # UTF-16 big-endian (rare: Java, some Mac formats)
strings -e S sample.bin # single 8-bit incl. high-ASCII (Latin-1 lures, some packers)
strings -t x sample.bin # prefix each string with its hex offset (-t d decimal, -t o octal) → jump there in a hex editor
strings -t x -e l sample.bin | grep -i 'cmd\|powershell\|http'
strings -a -n 6 sample.bin; strings -a -n 6 -e l sample.bin # ALWAYS run both — ASCII and UTF-16 — on Windows samples
strings -f *.bin # -f: print filename before each string (many files)
strings sample.bin | sort | uniq -c | sort -rn | head # repeated strings = table entries, decoy padding
strings sample.bin | awk 'length > 60' # long strings: base64 blobs, embedded scripts, URLs with parameters
| Platform | Equivalent |
|---|---|
| macOS | strings is from LLVM/cctools: strings -a sample.bin; no -e l — use iconv/python below, or brew install binutils → gstrings -e l |
| Windows | Sysinternals strings.exe -a -n 6 sample.bin scans ASCII and Unicode by default (-u Unicode only, -a ASCII only, -o offsets, -s recurse); bstrings (EZ Tools) adds regex and built-in IOC patterns — see EZ Tools |
| PowerShell | Select-String -Path sample.bin -Pattern 'http' -Encoding Unicode for a quick UTF-16 grep, or [IO.File]::ReadAllBytes + regex |
| Any | FLOSS (Mandiant floss sample.exe) — recovers obfuscated and stack strings from PE files that plain strings never sees; run it after strings disappoints |
# UTF-16 strings on macOS/Windows-less environments without -e l
python3 -c "import re,sys;d=open(sys.argv[1],'rb').read();print('\n'.join(m.group().decode('utf-16le') for m in re.finditer(rb'(?:[\x20-\x7e]\x00){6,}',d)))" sample.bin
Making strings output useful: the IOC pass
Save the full output once (strings -a -n 6 sample.bin > s.txt; strings -a -n 6 -e l sample.bin >> s.txt) and grep the file instead of re-running.
S=s.txt
grep -Eio 'https?://[a-z0-9./?=_%:-]+' $S | sort -u # URLs
grep -Eo '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' $S | sort -u | grep -Ev '^(0|127|255)\.' # IPv4 (drops version-number noise imperfectly — eyeball it)
grep -Eio '\b[a-z0-9.-]+\.(com|net|org|io|ru|cn|top|xyz|info|biz|onion|pw|cc|su)\b' $S | sort -u # domains
grep -Eio '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' $S | sort -u # emails
grep -Ei '\\\\[^\\ ]+\\[^\\ ]+' $S | sort -u # UNC paths
grep -Ei 'HKEY_|HKLM|HKCU|CurrentVersion\\Run|Software\\Microsoft' $S | sort -u # registry
grep -Ei '\.(exe|dll|bat|ps1|vbs|js|hta|scr|lnk|tmp|dat|log)\b' $S | sort -u # filenames
grep -Ei 'C:\\|%APPDATA%|%TEMP%|\\Temp\\|\\Users\\|/tmp/|/dev/shm|/var/tmp' $S | sort -u # paths
grep -Ei 'powershell|cmd\.exe|/c |-enc|-nop|-w hidden|IEX|Invoke-|DownloadString|FromBase64|wscript|cscript|mshta|rundll32|regsvr32|certutil|bitsadmin|schtasks|sc \|net user|whoami' $S # LOLBins & PS
grep -Ei 'CreateRemoteThread|VirtualAlloc|WriteProcessMemory|NtUnmapViewOfSection|SetWindowsHookEx|IsDebuggerPresent|GetTickCount|CryptEncrypt|InternetOpen|WinHttp|URLDownloadToFile|ShellExecute|WinExec|RegSetValue|AdjustTokenPrivileges|OpenProcess|LoadLibrary|GetProcAddress' $S | sort -u # suspicious imports
grep -Ei 'user-agent|mozilla/|accept:|content-type' $S # hardcoded HTTP client
grep -Ei 'password|passwd|pwd=|token|secret|api[_-]?key|BEGIN (RSA|OPENSSH|EC) PRIVATE|AKIA[0-9A-Z]{16}' $S # credentials
grep -Ei 'mutex|Global\\|Local\\' $S # mutex names → hunt on other hosts
grep -Ei 'pdb$|\.pdb\b|[A-Z]:\\Users\\[^\\]+\\(source|Desktop|Documents)' $S # PDB path = developer username & project name
grep -Ei 'upx|aspack|themida|vmprotect|mpress|petite|\.packed|this program cannot be run' $S # packer strings
grep -Eo '[A-Za-z0-9+/]{40,}={0,2}' $S | head # base64 blobs → decode below
grep -Eo '[0-9a-f]{32}\b|[0-9a-f]{40}\b|[0-9a-f]{64}\b' $S | sort -u | head # hashes / hex keys
grep -Eio '(bitcoin|btc|monero|xmr|wallet|\.onion|ransom|decrypt|your files)' $S # ransomware notes
# Decode what you found
echo 'SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQA' | base64 -d | iconv -f utf-16le -t utf-8 # PowerShell -enc is UTF-16LE base64
echo 'aHR0cDov...' | base64 -d | file - # what is inside the blob?
printf '\x68\x74\x74\x70' | xxd; echo 68747470 | xxd -r -p # hex ↔ bytes
python3 -c "import sys;print(''.join(chr(ord(c)^0x41) for c in open('blob','rb').read().decode('latin1')))" # single-byte XOR guess
# Brute-force single-byte XOR / ROT / base64 layers: CyberChef "Magic" op, or `xortool -c 20 blob`, or `unxor`
[!tip] Strings are cheap for the attacker to fake Decoy strings (legitimate-looking URLs, fake PDB paths, whole English dictionaries) are common in packed samples. A binary with almost no strings, or only library boilerplate, is more suspicious than one full of them: it is packed or the strings are built at runtime — run FLOSS, or dump it from memory after it unpacks (see Volatility
windows.dumpfiles/malfind).
Hex: xxd, hexdump, od, editors
xxd sample.bin | less # canonical: offset, hex, ASCII
xxd -s 0x3C -l 4 sample.bin # -s seek, -l length: read the PE header offset
xxd -s -64 sample.bin # last 64 bytes (appended data?)
xxd -c 32 -g 1 sample.bin | head # 32 bytes per line, grouped by 1
xxd -p sample.bin | head -c 200 # plain hex, no formatting (for grep / diff)
xxd -r -p hex.txt > out.bin # hex → binary
hexdump -C sample.bin | head # BSD-style canonical (macOS default)
od -A x -t x1z -v sample.bin | head # od: hex offsets, 1-byte hex, ASCII, no * for repeats
cmp -l a.bin b.bin | head # byte-level diff; `vbindiff a b`, `radiff2 -x a b` for visual
dd if=sample.bin bs=1 skip=$((0x1000)) count=512 2>/dev/null | xxd | head # cut a region
Format-Hex .\sample.bin -Offset 0x3C -Count 4
Format-Hex .\sample.bin | Select -Last 4
[BitConverter]::ToString((Get-Content .\sample.bin -Encoding Byte -TotalCount 16)) -replace '-',' '
GUI hex editors: HxD (Windows, free, huge files, disk/RAM editing, data inspector), ImHex (cross-platform, pattern language decodes structures for you, hex + entropy + strings + yara in one), 010 Editor (paid, binary templates for every format), hexyl (terminal, coloured). Registry hive, PE and NTFS record templates exist for all three — worth it when you need to read a structure by hand.
Metadata: exiftool
exiftool sample.jpg # everything: camera, GPS, timestamps, software, author
exiftool -G1 -a -s sample.docx # group names, all duplicates, tag names as they are in the file
exiftool -a -u -g1 -ee sample.pdf # unknown tags, embedded streams
exiftool -gps:all -n photo.jpg # coordinates in decimal
exiftool -Author -Creator -Producer -CreateDate -ModifyDate *.pdf *.doc* # who made the docs, with what
exiftool -r -csv -common -CreateDate -Author /mnt/img/home/*/Documents > docs.csv # recurse, CSV for Timeline Explorer
exiftool -time:all -a -G0:1 -s sample.docx # every timestamp incl. Office internal ones vs filesystem
exiftool -if '$gpslatitude' -r -p '$filename,$gpslatitude,$gpslongitude' . # only geotagged files
exiftool -X sample.jpg > meta.xml; exiftool -j sample.jpg > meta.json
exiftool -all= copy.jpg # strip (never on evidence — for your own redaction)
What to read: Office Creator/LastModifiedBy/Company/RevisionNumber/TotalEditTime/Template (normal.dotm vs something odd), Application and AppVersion (a “2019 Word” doc from a 2010 build); PDF Producer/Creator (LibreOffice, Microsoft: Print To PDF, mPDF from a webapp, Ghostscript), CreateDate vs ModifyDate, XMP history; images Make/Model/Software/GPSPosition/DateTimeOriginal, thumbnail that does not match the image (edited photo); LNK/EXE exiftool reads PE version info (CompanyName, OriginalFileName — a svchost.exe whose original name is stealer.exe).
Archives, containers, embedded objects
# Office docs are ZIPs — look inside without Office
unzip -l sample.docx; unzip -p sample.docx word/vbaProject.bin | file - # macro container present?
unzip -p sample.docx word/_rels/document.xml.rels | grep -io 'target="http[^"]*"' # remote template injection
unzip -p sample.docx docProps/core.xml docProps/app.xml # metadata XML
7z l sample.bin; 7z x -osample_extracted sample.bin # 7z opens almost anything: zip, cab, msi, iso, vhd, wim, chm, pe resources
binwalk sample.bin # signature scan for embedded files (firmware, but also polyglots and stego)
binwalk -e sample.bin # extract them (into _sample.bin.extracted/)
binwalk -E sample.bin # entropy graph — flat high entropy = encrypted/compressed/packed
binwalk -R '\x50\x4b\x03\x04' sample.bin # raw byte search with offsets
foremost -t all -i sample.bin -o carved/ # carve known types out of ANY blob (same tool as disk carving below)
# PE quick look (Linux) — imports, sections, entropy, timestamps
readpe -h sample.exe; readpe -i sample.exe | head -60 # pev
pescan sample.exe # pev heuristics
python3 -c "import pefile;p=pefile.PE('sample.exe');print(p.FILE_HEADER.dump());[print(e.dll,[i.name for i in e.imports][:8]) for e in p.DIRECTORY_ENTRY_IMPORT]"
diec sample.exe # Detect It Easy: compiler, packer, protector
# Windows GUI: pestudio (indicators, imports scored, strings, VT lookup), DiE, CFF Explorer, PE-bear
Documents: PDF and Office maldoc triage
# PDF
pdfid.py sample.pdf # counts of /JS /JavaScript /OpenAction /AA /Launch /EmbeddedFile /URI /ObjStm — any of the first five = open it further
pdf-parser.py -a sample.pdf # stats: objects by type
pdf-parser.py --search JavaScript sample.pdf # find the object
pdf-parser.py -o 12 -f -w sample.pdf # dump object 12, filters applied, raw
pdf-parser.py --search /Launch sample.pdf; pdf-parser.py --search /URI sample.pdf
peepdf -i sample.pdf # interactive; `js_analyse` / `extract js`
qpdf --qdf --object-streams=disable sample.pdf out.pdf # decompress everything so grep/strings work on it
strings out.pdf | grep -Ei 'javascript|/JS|/Launch|/URI|/EmbeddedFile|/OpenAction|cmd|powershell'
# Office (OLE and OOXML) — oletools
oleid sample.doc # summary: encrypted? VBA? XLM? external relationships? flash?
olevba sample.docm # dump macros + auto-exec triggers + suspicious keywords + IOCs table
olevba --decode --deobf sample.docm # decode hex/base64/StrReverse, attempt deobfuscation
olevba --reveal sample.docm # macro source with obfuscated strings replaced
oledump.py sample.doc # streams; 'M' = macro stream; -s 7 -v = decompress stream 7
oledump.py -p plugin_http_heuristics sample.doc
mraptor sample.doc # AutoExec + Write/Execute = suspicious, one line
rtfobj sample.rtf # embedded OLE objects in RTF (Equation Editor exploits)
msodde sample.docx # DDE field attacks
xlmdeobfuscator -f sample.xls # Excel 4.0 (XLM) macros
Hashing, fuzzy hashing, known-good/bad
sha256sum sample.bin; md5sum sample.bin; sha1sum sample.bin
hashdeep -c md5,sha1,sha256 -r ./samples/ > hashes.txt # recursive multi-hash
hashdeep -c sha256 -r -a -k known-good.txt ./bin/ # audit dir against a known set (-a audit, -k known)
hashdeep -c sha256 -r -m -k nsrl.txt /mnt/img/usr/bin # -m: show only files that MATCH known (whitelist noise)
hashdeep -c sha256 -r -x -k nsrl.txt /mnt/img/usr/bin # -x: show only UNKNOWN files — the review list
ssdeep -b sample.bin # context-triggered piecewise hash
ssdeep -bl -r ./samples/ > fuzzy.txt; ssdeep -bm fuzzy.txt new.bin # match a new sample against a set (score 0–100)
ssdeep -d -r ./samples/ # cluster near-duplicates within a directory
tlsh -f sample.bin # TLSH — better on small/heavily-modified files
# Look up, don't upload (an upload tells the attacker you found it):
# VirusTotal hash search, MalwareBazaar, Hybrid Analysis, `vt file <sha256>` CLI, ANY.RUN search
Get-FileHash .\sample.bin -Algorithm SHA256 # MD5, SHA1, SHA256, SHA384, SHA512
Get-ChildItem -Recurse | Get-FileHash -Algorithm SHA256 | Export-Csv hashes.csv
certutil -hashfile .\sample.bin SHA256 # no PowerShell
certutil -hashfile .\sample.bin MD5
sigcheck64.exe -a -h -vt .\sample.exe # Sysinternals: signature, version, hashes, VirusTotal (-vt requires accepting ToS)
sigcheck64.exe -e -u -vr -s C:\Windows\System32 > unsigned.txt # unsigned exes in a tree
Carving: files from unallocated space, swap, memory
# Get the blob: unallocated blocks of a partition (Sleuth Kit), or the whole image, or pagefile/hiberfil/mem
blkls -o 2048 disk.dd > unalloc.raw
# foremost — header/footer carving, config-driven, fast
foremost -t jpg,png,pdf,doc,zip,exe -i unalloc.raw -o carved-foremost/ # -t types (or all), writes audit.txt with offsets
foremost -c /etc/foremost.conf -i disk.dd -o carved/ # custom signatures in the conf
# scalpel — same idea, faster, edit /etc/scalpel/scalpel.conf to UNCOMMENT the types you want first
scalpel -c /etc/scalpel/scalpel.conf -o carved-scalpel/ unalloc.raw
# photorec — best for media (400+ formats), interactive TUI, works on damaged fs; /cmd for scripting
photorec /log /d carved-photorec/ /cmd disk.dd fileopt,everything,enable,search
# bulk_extractor — does NOT carve files; it scans EVERY byte for FEATURES: emails, URLs, IPs, phone numbers, credit cards,
# JSON, base64, EXIF, zip/gzip/rar contents (recursively decompressed!), Windows PE headers, hex keys, domains
bulk_extractor -o be-out/ disk.dd # 10–30 min per 100 GB; multi-threaded
bulk_extractor -o be-out/ -E email -E url -E domain -E exif unalloc.raw # -E enable only listed scanners
ls be-out/ # email.txt url.txt domain.txt ip.txt telephone.txt ccn.txt exif.txt zip.txt json.txt *_histogram.txt
head be-out/url_histogram.txt be-out/email_histogram.txt # ranked — top hits first
bulk_extractor -o be-out/ -F iocs.txt disk.dd # -F: search for your own list of strings (offsets to features.txt)
bulk_extractor -o be-out/ -f 'Invoke-|-enc ' disk.dd # -f: regex
# Every hit carries a byte offset (or "offset-ZIP-offset" for compressed) → dd/xxd there, or `fiwalk`/`identify_filenames.py` to map offset → filename via the fs
identify_filenames.py --all be-out/ be-out-annotated/ --image disk.dd
# Manual carving when you know the header: find offsets, cut
grep -obUaP '\xFF\xD8\xFF\xE0' unalloc.raw | head # -o offsets, -b byte offset, -U binary, -a text, -P perl regex
python3 - <<'PY'
import re
d=open('unalloc.raw','rb').read()
for i,m in enumerate(re.finditer(rb'%PDF-1\.\d.*?\x25\x25EOF', d, re.S)):
open(f'carved_{i}.pdf','wb').write(m.group()); print(i, m.start(), len(m.group()))
PY
# Strings over the whole blob, with offsets, into the IOC pass above
strings -a -t x -n 8 unalloc.raw > unalloc-strings.txt; strings -a -t x -n 8 -e l unalloc.raw >> unalloc-strings.txt
# Windows pagefile/hiberfil: strings + bstrings work directly; decompress hiberfil first for real analysis
# hibr2bin.exe hiberfil.sys hiber.raw (Comae/Magnet) then Volatility / strings on hiber.raw
[!info] What carving cannot do Fragmented files come out corrupt (only the first fragment, or garbage joined on). SSDs with TRIM zero deleted blocks quickly — carving an SSD imaged days after deletion mostly yields nothing. Encrypted/compressed containers carve as one opaque blob. Carved files have no name, no path, no timestamps: to get those back, match the carved file’s hash/offset to
$MFT/fls -ddeleted entries or the USN journal.
YARA: match what you already know
yara -r rules/ sample.bin # recurse a rules dir
yara -s rule.yar sample.bin # -s print matching strings + offsets
yara -m -s rules.yar sample.bin # -m print rule metadata
yara -r -w -f rules/ /mnt/img/home/ # -w no warnings, -f fast mode
yara -C compiled.yarc sample.bin; yarac rules/*.yar compiled.yarc # precompile big rule sets
yara rules.yar 1234 # scan a live PID (Linux, root)
yara -D sample.bin # dump module data (pe, elf, hash, math)
yara -d filename=sample.bin -d filesize=$(stat -c%s sample.bin) rules.yar sample.bin # external variables
yara-x scan rules/ sample.bin # yara-x: the Rust rewrite, same syntax, faster, better errors
rule triage_suspicious_pe_strings
{
meta:
author = "DAEMON"
description = "Quick triage: PE with injection APIs + a URL + a PowerShell flag"
strings:
$api1 = "VirtualAllocEx" ascii
$api2 = "WriteProcessMemory" ascii
$api3 = "CreateRemoteThread" ascii
$url = /https?:\/\/[a-z0-9.\-]+\/[a-z0-9\/._-]*/ ascii wide nocase
$ps = "-enc" ascii wide nocase
$ps2 = "FromBase64String" ascii wide
condition:
uint16(0) == 0x5A4D and filesize < 5MB and
2 of ($api*) and ($url or any of ($ps*))
}
Rule sources: Neo23x0/signature-base (Loki/Thor), Yara-Rules/rules, ReversingLabs, Elastic protections-artifacts, InQuest awesome-yara index, ESET, Malpedia (login), plus the packer/crypto/capability rules in mandiant/capa (capa sample.exe gives you ATT&CK capabilities without writing rules). Keep an iocs.yar per case with the hashes, mutexes, PDB paths and URLs you pulled out of strings — then scan every other host’s triage collection with it.
Ten-minute triage checklist
f=sample.bin
file -k $f; sha256sum $f; ssdeep -b $f; exiftool -G1 -s $f | head -40
xxd $f | head -4; xxd $f | tail -4
strings -a -n 6 $f > s.txt; strings -a -n 6 -e l $f >> s.txt; wc -l s.txt
grep -Eio 'https?://[^ "]+|\b([0-9]{1,3}\.){3}[0-9]{1,3}\b|[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' s.txt | sort -u
grep -Ei 'powershell|cmd\.exe|-enc|VirtualAlloc|WriteProcessMemory|CreateRemoteThread|HKCU|HKLM|\\Temp\\|\.pdb' s.txt | sort -u | head -40
binwalk $f | head; binwalk -E $f >/dev/null && echo "see entropy png"
diec $f 2>/dev/null || pescan $f 2>/dev/null
yara -r ~/rules/ $f; capa $f 2>/dev/null | head -40
# then decide: benign / known-bad (hash hit) / needs sandbox (ANY.RUN, CAPE, Joe) / needs a reverser
- Identity:
file -k, magic head/tail, size, entropy. Packed? Polyglot? Appended data? - Hashes: SHA-256 to VT/MalwareBazaar search (do not upload yet);
ssdeepagainst your case corpus. - Metadata:
exiftool— author, tool, timestamps, PDB path, version info vs filename. - Strings, both encodings, then the IOC greps. Save everything to the case notes with offsets.
- Structure: imports/sections (PE), objects (PDF), macros (Office), embedded files (
binwalk,7z l). - Match: YARA rule sets, capa. Write the case rule from what you found.
- Decide the next stop: sandbox, Volatility for a memory-resident stage, or a reverser.
Related
- EZ Tools & KAPE —
bstrings,Hasher,EZVieweron Windows - Linux forensics — where unallocated space comes from (
blkls), Sleuth Kit - Acquisition — getting the disk/memory image to carve
- Volatility 3 — dumping unpacked binaries from memory for a second
stringspass - Hashing — algorithm reference