$ cat writeup.md…
$ cat writeup.md…
HackTheBox
In the dust and sand surrounding the vault, you unearth a rusty PCB... You try to read the etched print, it says Open..W...RT, a router! You hand it over to the hardware gurus and to their surprise the ROM Chip is intact! They manage to read the data off the tarnished silicon and they give you back
In the dust and sand surrounding the vault, you unearth a rusty PCB... You try to read the etched print, it says Open..W...RT, a router! You hand it over to the hardware gurus and to their surprise the ROM Chip is intact! They manage to read the data off the tarnished silicon and they give you back a firmware image. It's now your job to examine the firmware and maybe recover some useful information that will be important for unlocking and bypassing some of the vault's countermeasures!
The challenge provided a firmware dump file (chal_router_dump.bin, 16MB) and a netcat service that asked questions about the firmware contents.
OpenWRT firmware typically consists of multiple partitions:
The key insight is that sensitive data (passwords, credentials, custom configs) are stored in the JFFS2 overlay, not the base SquashFS. This is because SquashFS is read-only and contains only default configurations.
| Filesystem | Magic Bytes | Hex |
|---|---|---|
| SquashFS | hsqs | 68 73 71 73 |
| JFFS2 | \x85\x19 | 85 19 |
# Find SquashFS signature xxd chal_router_dump.bin | grep -i "hsqs" # Found at offset 0x42c2c8 (4375240 decimal) # Extract SquashFS partition dd if=chal_router_dump.bin of=squashfs.bin bs=1 skip=4375240 # Mount/extract the filesystem unsquashfs -d rootfs squashfs.bin
From SquashFS we get:
/etc/openwrt_release → OpenWRT version: 23.05.0# Find JFFS2 magic bytes (0x1985 little-endian = 0x8519) xxd chal_router_dump.bin | grep "8519" # Found at offset 0x7c0000 # Extract JFFS2 partition dd if=chal_router_dump.bin of=jffs2.bin bs=1 skip=$((0x7c0000)) # Extract using jefferson (JFFS2 extraction tool) jefferson jffs2.bin -d jffs2_extracted
strings chal_router_dump.bin | grep -i "linux-" # Output: "MIPS OpenWrt Linux-5.15.134"
Linux kernel version: 5.15.134
JFFS2 contains the overlay filesystem with user modifications. Key files found:
# Shadow file with root password hash cat jffs2_extracted/work/work/#32 # root:$1$YfuRJudo$cXCiIJXn9fWLIt8WY2Okp1:19804:0:99999:7::: # Network configuration (PPPoE credentials) cat jffs2_extracted/work/work/#4/network # PPPoE username: yohZ5ah # PPPoE password: ae-h+i$i^Ngohroorie!bieng6kee7oh # Wireless configuration cat jffs2_extracted/work/work/#4/wireless # SSID: VLT-AP01 # WiFi password: french-halves-vehicular-favorable # Firewall rules with port redirects cat jffs2_extracted/work/work/#b # WAN redirect ports: 1778, 2289, 8088 # LAN redirect ports: 4431, 5881, 9889
#!/usr/bin/env python3 from pwn import * r = remote('83.136.253.144', 57317) answers = [ b'23.05.0', # OpenWRT version b'5.15.134', # Linux kernel b'root:$1$YfuRJudo$cXCiIJXn9fWLIt8WY2Okp1:19804:0:99999:7:::', # Root hash b'yohZ5ah', # PPPoE username b'ae-h+i$i^Ngohroorie!bieng6kee7oh', # PPPoE password b'VLT-AP01', # WiFi SSID b'french-halves-vehicular-favorable', # WiFi password b'1778,2289,8088', # WAN ports (sorted) b'4431,5881,9889', # LAN ports (sorted) ] for ans in answers: r.recvuntil(b'> ') r.sendline(ans) print(r.recvall().decode())
# Search for filesystems in firmware binwalk firmware.bin # Extract everything automatically binwalk -e firmware.bin # Manual signature search xxd firmware.bin | grep -E "hsqs|8519|7371" # Extract SquashFS unsquashfs -d output squashfs.bin # Extract JFFS2 jefferson jffs2.bin -d output # Search for strings in binary strings -n 8 firmware.bin | grep -i "password\|secret\|key"
/etc/openwrt_release - OpenWRT version
/etc/config/network - Network settings (PPPoE, WAN, LAN)
/etc/config/wireless - WiFi settings (SSID, password)
/etc/config/firewall - Firewall rules, port forwarding
/etc/shadow - User password hashes
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar