Imported from salmanabdurrahman/pi-pentest-agent (
skills/re-firmware/SKILL.md). Install upstream withnpx skills add salmanabdurrahman/pi-pentest-agent --skill re-firmware. Copyright stays with the author.
Firmware reverse engineering — safe offline extraction and analysis
Use this skill to analyze firmware images you are authorized to inspect. Firmware analysis involves extracting the filesystem, identifying architecture, discovering hardcoded credentials, reviewing boot scripts, and optionally emulating the firmware in an isolated sandbox. Keep extraction and static analysis offline by default. Dynamic emulation requires sandbox isolation, network-disabled, and explicit scope permission. Never flash extracted firmware back onto a device. Never deploy extracted binaries to production environments.
Required inputs
- Firmware image path with confirmed ownership or explicit authorization from the device vendor, asset owner, or engagement scope.
- SHA-256 hash of the firmware image computed before extraction and recorded in evidence.
- Isolated extraction environment (VM, container, or dedicated analysis machine). The environment must be revertible.
- Scope for extracted data handling: hardcoded credentials, certificates, private keys, and customer data found in the firmware must be redacted by default. Treat all embedded secrets as sensitive.
- Valid authorization cache when the firmware is from a customer engagement.
- Explicit approval for any dynamic emulation (QEMU full-system or chroot) — this is separate from static extraction permission.
Required gates
pentest_agent_load_configandpentest_agent_validate_policybefore planning.pentest_agent_parse_scopeto define firmware-handling boundaries, device-authorization domain, and data-classification rules.pentest_agent_validate_targetfor the firmware path and any device or vendor identifier.pentest_agent_check_authorizationbefore extraction, emulation, or any tool execution.pentest_agent_build_commandfor dry-run argv preview of binwalk, unsquashfs, and extraction tools.pentest_agent_execute_toolfor all tool invocation — keep network disabled for extraction.pentest_agent_append_evidencefor all extraction output, file listings, and credential notes.
Workflow
Phase 1 — firmware triage and architecture identification
- Hash the firmware image before any analysis:
sha256sum <firmware.bin>. Record the hash in evidence. - Work on a copy of the firmware, never the original. Copy to the isolated analysis environment and verify the hash after copy.
- File type and architecture:
file firmware.bin— identifies the firmware format (binary blob, U-Boot image, raw filesystem dump, compressed archive).binwalk firmware.bin— scans for embedded filesystem signatures, compression markers, and file headers. Output shows offsets and detected types (Squashfs, JFFS2, Cramfs, CPIO, LZMA, gzip, etc.).hexdump -C firmware.bin | head -40— manually inspect the first bytes. Common headers:hsqs(Squashfs),u-boot(U-Boot),28 01(JFFS2),45 46 49(JFFS2 little-endian).strings firmware.bin | head -100— quick string inspection to identify vendor, model, kernel version, build date.
- Entropy analysis:
binwalk -E firmware.bin. High-entropy regions indicate compressed or encrypted blocks. Low entropy sections are likely filesystem data or code. - Record: firmware filename, SHA-256, file size, detected architecture (MIPS, ARM, x86, PowerPC, RISC-V), endianness, and entropy profile.
Phase 2 — extraction and filesystem reconstruction
- Primary extraction with binwalk:
binwalk -e --run-as=root firmware.bin -C extracted/- This extracts all detected embedded files and filesystems. Common output: Squashfs images (
.squashfs), compressed CPIO archives, JFFS2 filesystem dumps, kernel images.
- Navigate the extraction tree:
cd extracted/_firmware.bin.extracted/. List all extracted artifacts:ls -la *.squashfs *.cpio *.jffs2 2>/dev/null. - Unpack Squashfs filesystem (most common for embedded Linux):
unsquashfs -d squashfs-root <file>.squashfs- Inspect the root filesystem:
ls squashfs-root/. Look for/etc,/bin,/sbin,/usr,/var,/www,/lib.
- Handle Cramfs:
sudo mount -o loop <file>.cramfs /mnt/cramfs && cp -a /mnt/cramfs/* ./cramfs-root/ && sudo umount /mnt/cramfs
- Handle JFFS2:
binwalk -e <file>.jffs2 --run-as=rootor usejeffersontool:jefferson <file>.jffs2 -d jffs2-root/
- Recursive deep extraction when nested filesystems exist:
binwalk -Me --run-as=root firmware.bin— the-Mflag recursively extracts until no further signatures are detected.- Check each extracted layer for additional embedded filesystems.
- Filesystem overview — record top-level structure:
find squashfs-root/ -maxdepth 2 -type d | sort- Identify: web root (
/www,/var/www,/htdocs), configuration directory (/etc), binary directories, startup scripts (/etc/init.d,/etc/rc.d), and custom application directories.
Phase 3 — credential and secret discovery
Systematically search for hardcoded credentials, cryptographic keys, and sensitive configuration data in the extracted filesystem.
- Authentication files:
cat squashfs-root/etc/passwd 2>/dev/null— user accounts. Flag non-system accounts (UID ≥ 1000).cat squashfs-root/etc/shadow 2>/dev/null— password hashes. Hash type prefix indicates algorithm:$1$(MD5, weak),$6$(SHA-512),$y$(yescrypt).cat squashfs-root/etc/htpasswd 2>/dev/null— web server authentication. Flag cleartext or weakly hashed passwords.
- Config file credential search:
grep -rn "password\|passwd\|pass\s*=" squashfs-root/etc/ --include="*.conf" --include="*.cfg" --include="*.ini" --include="*.xml" --include="*.json" 2>/dev/null | head -50grep -rn "secret\|token\|apikey\|api_key\|auth" squashfs-root/etc/ --include="*.conf" --include="*.cfg" 2>/dev/null | head -30
- Private key and certificate discovery:
find squashfs-root/ -name "*.pem" -o -name "*.key" -o -name "*.crt" -o -name "*.p12" -o -name "*.pfx" 2>/dev/nullgrep -rn "BEGIN RSA PRIVATE KEY\|BEGIN PRIVATE KEY\|BEGIN CERTIFICATE\|BEGIN DSA PRIVATE KEY" squashfs-root/ 2>/dev/null- Flag all private keys found. These may enable impersonation, decryption, or MITM attacks on the device communications.
- Embedded credentials in binaries:
find squashfs-root/usr/sbin/ squashfs-root/usr/bin/ squashfs-root/bin/ -type f -executable 2>/dev/null | while read f; do strings "$f" 2>/dev/null | grep -iE "password|secret|admin|root" | grep -v "^$" ; done | sort -u | head -40- This catches credentials compiled into binaries, not present in config files.
- Hardcoded URLs and IPs:
grep -rn "https\?://" squashfs-root/ --include="*.conf" --include="*.sh" --include="*.lua" 2>/dev/null | head -30- Flag: update server URLs, telemetry endpoints, cloud-API endpoints. These reveal the device's external communication targets.
- Default credentials database cross-reference:
- Compare discovered credentials against known default-password databases only as a documentation aid — never attempt to authenticate to a live device without separate authorization.
Phase 4 — boot-script and service analysis
Understand what runs on the device at startup and what network services are exposed.
- Init scripts:
ls squashfs-root/etc/init.d/ squashfs-root/etc/rc.d/ squashfs-root/etc/rc?.d/ 2>/dev/null. Review each init script for:- Services started:
httpd,telnetd,sshd,ftpd,snmpd,upnpd. - Hardcoded arguments:
grep -E "^\s*(start\|/usr/sbin\|/usr/bin)" <init-script>. - Debug/dev flags left enabled:
grep -iE "debug\|verbose\|dev\|test" <init-script>.
- Services started:
- Inetd/xinetd configuration:
cat squashfs-root/etc/inetd.conf squashfs-root/etc/xinetd.conf squashfs-root/etc/xinetd.d/* 2>/dev/null- These configure on-demand network services. Flag any service enabled that shouldn't be.
- Cron jobs:
ls squashfs-root/etc/cron* squashfs-root/var/spool/cron/ 2>/dev/null. Review periodic tasks for:- Update checks contacting external URLs.
- Log rotation that may expose sensitive data.
- Cleanup scripts that could be exploited for persistence.
- BusyBox applet listing:
strings squashfs-root/bin/busybox 2>/dev/null | grep -oE "[a-z]+" | sort -u | head -30. BusyBox is a multi-call binary — the compiled-in applets reveal all available commands. Flag dangerous applets:telnetd,ftpd,tftpd,httpd,nc.
Phase 5 — binary vulnerability triage
Identify binaries that may contain exploitable vulnerabilities. This is triage-level only — deep binary analysis is delegated to the re-static and re-dynamic skills.
- Web server binary:
find squashfs-root/ -name "httpd" -o -name "lighttpd" -o -name "nginx" -o -name "uhttpd" -o -name "goahead" 2>/dev/null. Check:- Architecture:
file <httpd_binary> - Mitigations:
checksec --file=<httpd_binary>orreadelf -l <httpd_binary> | grep -E "GNU_STACK|GNU_RELRO". Record NX, Stack Canary, RELRO, PIE status. - Dangerous function imports:
objdump -T <httpd_binary> | grep -E "system|popen|execve|strcpy|gets|sprintf". Flag any of these — they indicate potential command injection or buffer overflow vectors.
- Architecture:
- CGI scripts:
find squashfs-root/ -name "*.cgi" -o -name "*.sh" -path "*/cgi-bin/*" 2>/dev/null. Review each CGI:grep -n "system\|exec\|popen\|eval\|\" <cgi_script>` — command injection vectors.grep -n "echo\|print\|cat" <cgi_script>— potential XSS or information disclosure.- Flag any CGI that passes user input to a shell command without sanitization.
- SUID binaries:
find squashfs-root/ -perm -4000 -type f 2>/dev/null. SUID binaries execute with elevated privileges. Flag any unexpected SUID binary — these are privilege-escalation candidates. - Outdated or vulnerable software versions:
grep -r "version\|VERSION" squashfs-root/etc/ --include="*.conf" 2>/dev/null | head -20. Cross-reference against known CVEs for the identified versions.
Phase 6 — QEMU emulation (sandboxed, network-disabled)
Emulate the firmware only when scope explicitly permits dynamic execution and the analysis requires runtime behavior observation. Never connect the emulated firmware to a production network.
- Determine architecture:
file squashfs-root/bin/busyboxorfile squashfs-root/bin/sh. Typical output:ELF 32-bit MSB executable, MIPS→ useqemu-mips-staticELF 32-bit LSB executable, ARM→ useqemu-arm-staticELF 64-bit LSB executable, ARM aarch64→ useqemu-aarch64-static
- Copy the static QEMU binary into the filesystem:
cp /usr/bin/qemu-mips-static squashfs-root/usr/bin/
- Chroot into the filesystem:
sudo chroot squashfs-root /usr/bin/qemu-mips-static /bin/sh
- Inside the chroot, explore:
ls /— verify the filesystem is intact.cat /etc/passwd— confirm user accounts.ps aux(if/procis mounted) — check for running services.
- Start a target service (web server) for local-only interaction:
/usr/sbin/httpd -p 8080or/bin/busybox httpd -p 8080 -h /www- From the host, interact only locally:
curl http://localhost:8080/. Never expose the emulated service to a network interface.
- After analysis, revert the sandbox to clean state. Never leave the emulated firmware running.
Decision points
- Firmware is encrypted: if extraction fails and binwalk shows only high-entropy data, the firmware may be encrypted with a vendor-specific key. Stop extraction and document the encryption. Decrypting vendor-encrypted firmware may violate license terms — check scope and legal guidance before attempting decryption.
- Firmware contains third-party licensed components: if the filesystem includes third-party binaries (e.g., commercial RTOS, licensed middleware), restrict analysis to configuration and text files. Do not reverse-engineer third-party binaries without separate legal approval.
- Credentials found are still valid on live devices: do NOT test the credentials against a live device without separate authorization for active testing. Record the finding as a credential-exposure vulnerability with the evidence path.
- SUID binary with command injection in a CGI script: this is a high-severity chain — flag as finding with exploit chain documentation. Do NOT develop or test the exploit without explicit scope permission.
- Dynamic emulation required: escalate to
re-dynamicskill for full sandbox execution. The firmware filesystem can be treated as the target environment for dynamic binary analysis. - Downgrade to static-only: if the firmware uses a CPU architecture for which no QEMU user-mode emulation is available, or if the kernel requires hardware-specific peripherals.
Prohibited behavior
- Flashing extracted or modified firmware onto live devices — prohibited unconditionally.
- Connecting emulated firmware to any network (LAN, WAN, internet) — network-disabled is the default. Only enable controlled network if scope explicitly permits and the network is fully isolated from production.
- Deploying firmware binaries to production, staging, or third-party environments.
- Extracting and reusing device private keys, vendor signing keys, or PKI certificates for any purpose beyond analysis documentation.
- Attempting to authenticate to live devices using credentials discovered in firmware without separate active-testing authorization.
- Bypassing device authentication, encryption, or secure-boot mechanisms to extract firmware that the vendor has locked down — this is a separate legal and scope boundary.
- Sharing firmware images or extracted filesystems outside the engagement scope.
Stop conditions
- Firmware extraction reveals third-party copyrighted or licensed data beyond the engagement scope → stop, document scope boundary exceeded, do not store or analyze the third-party material.
- Dynamic emulation attempts to establish outbound network connections → stop the emulation, revert the sandbox, document the connection targets.
- Credential search reveals credentials for systems outside the engagement scope → stop, redact the credentials from evidence, do not store them.
- Firmware architecture is unsupported by available tooling and scope does not authorize acquisition of additional analysis tools → document the limitation, hand off findings from accessible layers.
- Artifact triggers anti-tamper or self-destruct mechanisms during extraction → stop, document the anti-tamper behavior, revert to clean environment, record the technique as a finding.
Depth rules
- Confirm firmware ownership or authorization from vendor/asset owner before any analysis.
- Prefer offline/static extraction and filesystem review. Dynamic emulation is gated behind explicit scope and sandbox approval.
- Hash the firmware image before extraction and record the hash in all evidence. Work exclusively on copies.
- Record tool versions, extraction offsets, filesystem paths, architecture, endianness, and entropy profile.
- Treat every hardcoded credential, private key, and certificate as sensitive. Redact from default evidence. Store raw values only when
storeRawOutputis explicitly enabled and the finding requires credential evidence. - Do not bypass encryption, secure boot, or vendor lock mechanisms unless explicitly authorized in scope.
Evidence
For each firmware analysis session, produce an extraction record:
Firmware: <filename> (SHA-256: abcdef...)
Vendor/Model: <vendor> / <model> (if identified)
Architecture: MIPS big-endian (or ARM little-endian, etc.)
Size: 8,388,608 bytes
Extraction method: binwalk -e → Squashfs → unsquashfs
Filesystem root: squashfs-root/
Phase 3 — Credential discovery:
/etc/passwd:
root:x:0:0:root:/root:/bin/sh
admin:$1$salt$hash:1000:1000:admin:/home/admin:/bin/sh
→ MD5-crypt password hash (weak) — cracking feasible with rockyou.
/etc/shadow:
admin:$1$salt$hash:19000:0:99999:7:::
→ Password aging disabled (99999 days). Hash algorithm: MD5-crypt.
/etc/lighttpd.conf:
auth.backend.htpasswd.userfile = "/etc/htpasswd"
→ htpasswd file present: admin:$apr1$salt$hash (Apache MD5).
Phase 4 — Services identified:
Init script /etc/init.d/rcS:
/usr/sbin/httpd -p 80
/usr/sbin/telnetd -l /bin/sh
→ Telnet daemon started without authentication. Critical finding.
/etc/inetd.conf: (empty — not used)
Phase 5 — Binary triage:
/usr/sbin/httpd: ELF 32-bit MSB, MIPS, statically linked
checksec: No RELRO, No Canary, NX disabled, No PIE
→ All mitigations absent. Stack overflow → direct shellcode execution.
objdump -T: system@GLIBC_2.0, popen@GLIBC_2.0, sprintf@GLIBC_2.0
→ system() and popen() imported — command injection likely.
Findings:
[CRITICAL] Telnet daemon without authentication — unauthenticated root shell on the device.
[HIGH] Hardcoded admin credentials in /etc/htpasswd (Apache MD5 hash — crackable offline).
[HIGH] HTTP daemon compiled with all exploit mitigations disabled (No RELRO, No Canary, NX disabled, No PIE).
[MEDIUM] system() and popen() imported in httpd — potential command injection.
[INFO] Password aging disabled for admin account.
Aggregate findings per firmware image: credential inventory, exposed services, binary-mitigation summary, outdated-software CVEs, and exploit-chain candidates. Map each finding to the filesystem path where the evidence was discovered.
Never store: the raw firmware image in evidence (store only the SHA-256 hash), unredacted private keys or certificates, cleartext customer or user data, or extracted filesystems containing third-party proprietary code.
Report handoff
pentest_agent_record_findingfor each significant discovery: hardcoded credentials, exposed services with weak or no authentication, binaries with missing exploit mitigations, command-injection vectors, and SUID binaries.- Package findings with: firmware metadata (vendor, model, version, SHA-256), extraction method summary, filesystem architecture, credential inventory (redacted), service inventory with risk rating, and binary mitigation summary.
- Recommend: firmware update to remove hardcoded credentials and disable debug services, recompile binaries with full exploit mitigations (RELRO, Stack Canary, NX, PIE, FORTIFY_SOURCE), remove or authenticate Telnet/SSH access, implement signed firmware updates, and rotate all embedded credentials and private keys.
- Explicitly note: all analysis was performed on a copy of the firmware in an isolated environment, no live devices were contacted or modified, no credentials were tested against production systems, and the sandbox was reverted after dynamic analysis.