Firmware image extraction with binwalk and firmware-mod-kit — recursive archive carving, squashfs/jffs2/ubifs mounting, entropy analysis to detect packed/encrypted regions, and nested container handling. Entry point for all static filesystem analysis after a raw binary image is acquired.
64
76%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Medium
Suggest reviewing before use
Fix and improve this skill with Tessl
tessl review fix ./packages/decepticon/decepticon/skills/standard/iot/binwalk-extract/SKILL.mdTurn a raw binary image into a navigable filesystem tree. binwalk handles most common containers; firmware-mod-kit covers special-case squashfs variants; manual mounting handles the rest.
firmware-acquisition skill).binwalk (≥ 2.3), sasquatch (non-standard squashfs decompressor),
jefferson (JFFS2 extractor), ubireader (UBI/UBIFS), mtd-utils,
firmware-mod-kit (FMK), 7-zip, lzma, xz-utils.# Kali / Debian install
sudo apt-get install -y binwalk firmware-mod-kit mtd-utils
pip3 install jefferson ubireader
# sasquatch (handles non-standard squashfs compression: LZMA, XZ, ZLIB with vendor patches)
git clone https://github.com/devttys0/sasquatch && cd sasquatch
./build.sh && sudo cp sasquatch /usr/local/bin/FW=/workspace/evidence/iot/<target>/firmware/flash_full.bin
# Quick filetype + offset scan
binwalk "$FW"
# Entropy analysis: flat line near 1.0 = encrypted/compressed; structured = filesystem
binwalk -E "$FW"
# Output plot to PNG for report
binwalk -E --save "$FW" # saves <fw>.png beside the binary
# High entropy region with no signature = encrypted blob — note offset + size
# Low-to-medium entropy with known FS signature = squashfs/jffs2/cramfs — extract| Entropy range | Interpretation |
|---|---|
| 0.0–0.3 | Mostly zero-fill / padding — skip |
| 0.5–0.8 | Structured data (FS headers, ELF) — extract |
| 0.8–0.95 | Compressed data (gzip, lzma, zlib) — normal |
| 0.95–1.0 flat | AES/RSA encrypted or already-compressed blob — flag for key hunt |
OUTDIR=/workspace/evidence/iot/<target>/extracted
# Recursive extraction (-M), follow symlinks (-r), output to dedicated dir (-C)
binwalk -eM -C "$OUTDIR" "$FW"
# Inspect what was carved
find "$OUTDIR" -maxdepth 4 -type f | head -60
ls -lah "$OUTDIR"/_*_flash_full.bin.extracted/
squashfs-root/ ← mounted squashfs rootfs
40 ← raw uImage kernel (strip 64-byte header for vmlinuz)
40.7z ← carved archive at offset 0x40
A00000 ← raw block at offset 0xA00000SQFS=$(find "$OUTDIR" -name "*.squashfs" -o -name "squashfs-root.img" 2>/dev/null | head -1)
# Standard unsquashfs
unsquashfs -d /tmp/squashfs_root "$SQFS"
# Non-standard (Broadcom LZMA, TP-Link XZ, vendor-patched):
sasquatch -d /tmp/squashfs_root "$SQFS"
# If both fail, force a specific compression type:
sasquatch -p 1 -le -d /tmp/squashfs_root "$SQFS" # little-endian
sasquatch -p 1 -be -d /tmp/squashfs_root "$SQFS" # big-endian
# Verify extraction
ls /tmp/squashfs_root/{bin,etc,lib,usr,var} 2>/dev/nullJFFS2_IMG=$(find "$OUTDIR" -name "*.jffs2" 2>/dev/null | head -1)
# Method A: jefferson (Python, handles most variants)
jefferson "$JFFS2_IMG" -d /tmp/jffs2_root
# Method B: kernel loop mount (requires modprobe jffs2 + mtdram)
sudo modprobe mtdram total_size=65536 erase_size=256
sudo modprobe mtdblock
sudo dd if="$JFFS2_IMG" of=/dev/mtd0
sudo mount -t jffs2 /dev/mtdblock0 /mnt/jffs2UBI_IMG=$(find "$OUTDIR" -name "*.ubi" -o -name "*.ubifs" 2>/dev/null | head -1)
# ubireader_extract_files: most direct path
ubireader_extract_files -o /tmp/ubifs_root "$UBI_IMG"
# For raw UBI volume images, ubiextract:
sudo modprobe ubi
sudo ubiattach -m 0 -d 0 /dev/ubi_ctrl
sudo mount -t ubifs /dev/ubi0_0 /mnt/ubifs# Find filesystem magic bytes manually
python3 -c "
import sys
data = open('$FW','rb').read()
sigs = {b'hsqs': 'SquashFS LE', b'sqsh': 'SquashFS BE',
b'\\x19\\x85': 'JFFS2', b'UBI#': 'UBI', b'\\x27\\x05\\x19\\x56': 'uImage'}
for sig, name in sigs.items():
off = 0
while True:
idx = data.find(sig, off)
if idx == -1: break
print(f' {name} @ 0x{idx:08x}')
off = idx + 1"
# Carve a specific region for separate analysis
dd if="$FW" bs=1 skip=$((0xA00000)) count=$((0x600000)) of=/tmp/carved_rootfs.bin
# Run binwalk on the carved piece
binwalk -eM -C /tmp/carved_extract /tmp/carved_rootfs.bin# Device firmware often wraps: .zip/.tar → signed header → lzma → squashfs
# firmware-mod-kit handles multi-layer TP-Link / Netgear / Asus formats:
cd /opt/firmware-mod-kit
./extract-firmware.sh "$FW"
ls /tmp/fmk/
# D-Link WRGG (proprietary container):
binwalk --dd='.*' "$FW" # dump ALL matched signatures
file _*.extracted/*
# Lzma-raw regions binwalk missed (entropy ~0.9, no gzip magic):
lzma -d < /tmp/region.lzma > /tmp/region.decompressed
xz -d < /tmp/region.xz > /tmp/region.decompressedROOT=/tmp/squashfs_root # adjust to wherever rootfs landed
# Architecture + OS identification
file "$ROOT/bin/busybox"
readelf -h "$ROOT/bin/busybox" | grep -E "Machine|Class|Data"
# Enumerate interesting paths
ls "$ROOT/etc/"
ls "$ROOT/usr/bin/" | head -40
find "$ROOT" -name "*.conf" -o -name "*.ini" -o -name "*.cfg" | head -30
# SUID / SGID binaries (potential priv-esc on device)
find "$ROOT" -perm -u=s -type f 2>/dev/null
find "$ROOT" -perm -g=s -type f 2>/dev/null
# World-writable directories (writeable by web/telnet processes)
find "$ROOT" -perm -o=w -type d 2>/dev/null | grep -v proc
# Symlinks that escape the rootfs (path traversal potential)
find "$ROOT" -type l | while read l; do
target=$(readlink "$l")
echo "$l -> $target"
done | grep '^\.\.'EVDIR=/workspace/evidence/iot/<target>/extracted
mkdir -p "$EVDIR"
# Save extraction tree summary
find /tmp/squashfs_root -type f > "$EVDIR/file_tree.txt"
# Save entropy plot
cp "$FW.png" "$EVDIR/entropy_plot.png" 2>/dev/null || true
# Note encrypted regions for follow-up
echo "Encrypted blob @ 0xXXXXXX, length 0xYYY — likely AES-CBC, key TBD" \
>> "$EVDIR/notes.txt"binwalk -eM can write gigabytes if the firmware contains recursive containers;
run on a dedicated partition or tmpfs with sufficient space.bootloader-uboot skill).https://github.com/ReFirmLabs/binwalk/wikihttps://github.com/devttys0/sasquatchhttps://github.com/sviehb/jeffersonhttps://github.com/jrspruitt/ubi_readerhttps://github.com/rampageX/firmware-mod-kit0cf691e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.