Skip to main content

hardcoded-creds

Systematic hunt for hardcoded credentials, API keys, certificates, and default passwords in extracted IoT firmware. Covers /etc/shadow and passwd parsing, busybox httpd configs, telnet/dropbear stanzas, MQTT/cloud API key extraction, and cross-referencing against known default-credential databases.

Datos de origen

Repositorio
BitterSecurity/Decepticon
Última actividad en el origen
30 de mayo de 2026 a las 11:59
Idioma detectado de SKILL.md
inglés
Estrellas
5611
Forks
1061

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
hardcoded-creds
description
Systematic hunt for hardcoded credentials, API keys, certificates, and default passwords in extracted IoT firmware. Covers /etc/shadow and passwd parsing, busybox httpd configs, telnet/dropbear stanzas, MQTT/cloud API key extraction, and cross-referencing against known default-credential databases.
allowed-tools
Bash Read Write
metadata
{"subdomain":"iot","when_to_use":"hardcoded credentials, default password, busybox, telnet creds, SSH key, API key embedded, /etc/shadow, httpd config, dropbear key, hardcoded secret, firmware credentials, MQTT creds, default login","tags":"iot, credentials, hardcoded, shadow, passwd, busybox, httpd, telnet, dropbear, api-key, default-creds, embedded, firmware","mitre_attack":"T1552.001, T1078.001, T1110.001, T1552.004"}
# Hardcoded Credentials > Extracted rootfs often contains plaintext or weakly hashed credentials, > embedded TLS private keys, cloud API tokens, and hardcoded admin accounts. > This playbook covers the full triage path from raw rootfs to validated cred. ## Prerequisites - Extracted rootfs from `binwalk-extract` skill (path: `/tmp/squashfs_root` or similar). - Tools: `john`, `hashcat`, `openssl`, `trufflehog`, `strings`, standard GNU utilities. ```bash ROOT=/tmp/squashfs_root # set once; referenced throughout ``` --- ## Phase 1 — Account Databases ### /etc/passwd + /etc/shadow ```bash # Check for non-standard shells (telnetd, /bin/sh) and disabled-but-present accounts grep -v "nologin\|false" "$ROOT/etc/passwd" # Extract hashed passwords cat "$ROOT/etc/shadow" 2>/dev/null || echo "shadow not present" # Identify hash types # $1$ = MD5, $5$ = SHA-256, $6$ = SHA-512, $y$ = yescrypt, no-$ = DES awk -F: '{print $1, $2}' "$ROOT/etc/shadow" | grep -v '^\*\|^!\|^:$' # Crack with hashcat (shadow format) hashcat -m 1800 "$ROOT/etc/shadow" /usr/share/wordlists/rockyou.txt # $6$ SHA-512 hashcat -m 500 "$ROOT/etc/shadow" /usr/share/wordlists/rockyou.txt # $1$ MD5 hashcat -m 1500 "$ROOT/etc/shadow" /usr/share/wordlists/rockyou.txt # DES # john fallback (handles multi-type auto) unshadow "$ROOT/etc/passwd" "$ROOT/etc/shadow" > /tmp/unshadowed.txt john /tmp/unshadowed.txt --wordlist=/usr/share/wordlists/rockyou.txt john /tmp/unshadowed.txt --show ``` ### BusyBox-specific user configs ```bash # BusyBox httpd uses /etc/httpd.conf for auth find "$ROOT/etc" -name "httpd.conf" -o -name ".htpasswd" | xargs cat 2>/dev/null # BusyBox udhcpd / telnetd startup stanzas grep -r "telnetd\|login\|password" "$ROOT/etc/inittab" "$ROOT/etc/init.d/" \ "$ROOT/etc/rc.d/" 2>/dev/null | grep -v "^Binary" # BusyBox shadow format check (some use MD5 without $1$ prefix) grep -E '^[^:]+:[^:!*]{3,}' "$ROOT/etc/shadow" 2>/dev/null ``` --- ## Phase 2 — SSH / Dropbear Keys ```bash # Host keys (baked into firmware = same key across all units of same model) find "$ROOT" -name "dropbear_*_host_key" -o -name "ssh_host_*_key" 2>/dev/null # Convert Dropbear key to OpenSSH PEM for use dropbearconvert dropbear openssh "$ROOT/etc/dropbear/dropbear_rsa_host_key" \ /tmp/host_rsa.pem openssl rsa -in /tmp/host_rsa.pem -text -noout | head -20 # Authorized keys embedded for backdoor accounts find "$ROOT" -path "*/.ssh/authorized_keys" | xargs cat 2>/dev/null # Check if root has a passwordless authorized_key → instant SSH root on any unit grep -r "authorized_keys\|ssh-rsa\|ecdsa-sha2" "$ROOT" 2>/dev/null | head -10 ``` --- ## Phase 3 — Web Interface Credentials ```bash # CGI / Lua / PHP / lighttpd configs find "$ROOT" -name "*.lua" -o -name "*.cgi" -o -name "*.php" | \ xargs grep -l "password\|passwd\|credential\|secret\|admin" 2>/dev/null | head -20 # Plaintext credentials in web config files grep -rn "admin\|password\|passwd\|secret\|token" \ "$ROOT/etc/lighttpd/" "$ROOT/etc/nginx/" "$ROOT/etc/httpd/" 2>/dev/null # Hardcoded credentials in Lua/CGI scripts grep -rn '"admin"\|"root"\|"1234"\|"password"' "$ROOT/usr/lib/lua/" \ "$ROOT/www/" "$ROOT/usr/share/www/" 2>/dev/null | head -30 ``` --- ## Phase 4 — Strings-Based Secret Sweep ```bash # Broad strings dump: capture all printable sequences ≥ 8 chars find "$ROOT" -type f -executable | while read f; do strings "$f" 2>/dev/null done > /tmp/all_strings.txt # Filter credential-like patterns grep -iE 'password|passwd|secret|api.?key|token|credential|auth' /tmp/all_strings.txt \ | grep -vE '^(#|//|<!|<html|<head)' | sort -u | head -100 # AWS / GCP / Azure key patterns grep -E 'AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z_-]{35}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' \ /tmp/all_strings.txt # JWT tokens grep -oP 'eyJ[A-Za-z0-9+/=]+\.[A-Za-z0-9+/=]+\.[A-Za-z0-9+/=_-]+' \ /tmp/all_strings.txt | head -10 ``` ### trufflehog filesystem scan ```bash # trufflehog works on directories — point at rootfs trufflehog filesystem "$ROOT" --only-verified 2>/dev/null # Without --only-verified for broader sweep: trufflehog filesystem "$ROOT" --json 2>/dev/null | \ python3 -c "import sys,json; [print(json.dumps(r, indent=2)) for r in map(json.loads, sys.stdin)]" ``` --- ## Phase 5 — MQTT / Cloud / IoT-Platform Tokens ```bash # MQTT broker credentials grep -rn "mqtt\|MQTT\|mosquitto" "$ROOT" --include="*.conf" --include="*.cfg" \ --include="*.json" --include="*.lua" 2>/dev/null | head -30 # Cloud platform tokens (Tuya, HomeKit, AWS IoT, Azure IoT Hub) grep -rn "tuya\|homekit\|awsiot\|azure.*iot\|device_key\|productKey\|deviceSecret" \ "$ROOT" --include="*.json" --include="*.conf" 2>/dev/null | head -30 # PCB-serial-derived default PSK (check if device ID used as secret) grep -rn "serial\|SerialNum\|MAC\|mac_addr" "$ROOT/etc/config/" 2>/dev/null | head -20 ``` --- ## Phase 6 — Default Credential Matrix Cross-Reference ```bash # Extract all discovered usernames USERS=$(grep -v 'nologin\|false\|halt\|sync\|shutdown' "$ROOT/etc/passwd" | \ awk -F: '{print $1}' | tr '\n' ' ') echo "Accounts found: $USERS" # Cross-reference against routersploit / seclists default creds # RouterSploit default cred wordlist path (if installed): DFLT=/usr/share/routersploit/resources/wordlists/default_passwords.txt [ -f "$DFLT" ] && echo "Default wordlist available: $DFLT" # SecLists IoT default creds SECLIST=/usr/share/seclists/Passwords/Default-Credentials/default-passwords.csv [ -f "$SECLIST" ] && grep -iE 'admin|root|user' "$SECLIST" | head -20 ``` ### Known vendor default credential matrix | Vendor | Username | Password | Protocol | |---|---|---|---| | TP-Link (pre-2022) | admin | admin | HTTP / Telnet | | Netgear | admin | password | HTTP | | D-Link | admin | (blank) | HTTP | | Asus (stock) | admin | admin | HTTP | | MikroTik | admin | (blank) | SSH / Winbox | | Hikvision | admin | 12345 | RTSP / HTTP | | Dahua | admin | admin | HTTP | | Ubiquiti AirOS | ubnt | ubnt | SSH | | Western Digital MyCloud | admin | (blank) | HTTP | | Seagate NAS | admin | admin | HTTP | --- ## Phase 7 — TLS Certificate Private Keys ```bash # Find PEM-encoded private keys grep -rl "BEGIN.*PRIVATE KEY\|BEGIN RSA PRIVATE KEY" "$ROOT" 2>/dev/null # Find DER-format keys (binary — look for SEQUENCE headers) find "$ROOT" -name "*.der" -o -name "*.key" -o -name "*.pem" | while read f; do openssl rsa -in "$f" -text -noout 2>/dev/null | head -3 && echo "FILE: $f" done # Verify if vendor CA cert is self-signed (same key on all units = MitM vector) find "$ROOT" -name "*.crt" -o -name "*.pem" | while read f; do openssl x509 -in "$f" -noout -subject -issuer 2>/dev/null && echo " FILE: $f" done # Check if the private key matches the certificate openssl x509 -noout -modulus -in "$ROOT/etc/ssl/server.crt" | openssl md5 openssl rsa -noout -modulus -in "$ROOT/etc/ssl/server.key" | openssl md5 # Matching MD5 = key pair is valid and present on device ``` --- ## Evidence ```bash EVDIR=/workspace/evidence/iot/<target>/credentials mkdir -p "$EVDIR" # Save cred findings john /tmp/unshadowed.txt --show > "$EVDIR/cracked_passwords.txt" cp /tmp/all_strings.txt "$EVDIR/strings_all.txt" # Record each finding as a credential node # kg_add_node( # kind="credential", # label="Hardcoded admin credential in /etc/shadow", # props={ # "key": "iot-cred::<target>::admin", # "secret_type": "unix_password", # "username": "admin", # "hash": "<hash>", # "plaintext": "<if cracked>", # "source": "firmware /etc/shadow", # }, # ) ``` ## OPSEC Notes - Cracked shadow credentials are valid on every unit of the same firmware version (until the vendor patches). Document model + firmware version precisely. - Private key extraction enables MitM against the vendor's cloud API for all devices using that firmware. Escalate finding severity accordingly. - MQTT tokens with `#` wildcard subscriptions allow full telemetry interception across the vendor's entire fleet — flag as Critical if RoE scope allows cloud testing. ## References - SecLists default credentials: `https://github.com/danielmiessler/SecLists/tree/master/Passwords/Default-Credentials` - RouterSploit modules: `https://github.com/threat9/routersploit` - trufflehog: `https://github.com/trufflesecurity/trufflehog` - Hashcat hash-modes: `https://hashcat.net/wiki/doku.php?id=hashcat`
Ver en GitHub