I love hacking. I love vulnerability research. I love software exploitation. I love finding creative ways to subvert control of an application or system to make it do something it wasn't intended to do.
But this is research, and like any research, lots of things never pan out. It's weird because it involves hours, often hundreds or even thousands of hours, of frustration paid off by successes that last only moments. And the cycle repeats.
In order to develop an exploit we spend countless hours dissecting hardware and software looking for an oversight or misstep on the part of the developer. We follow dead end paths, only to realize they're dead ends days or weeks in. We often spend even more time wrestling with tools, trying to get them to work the way they should or to work together properly. When there isn't a tool already available we spend hours developing one that will help answer an esoteric question or shine light in a dark crevice.
When nothing's going right and at the height of frustration, I'm known to mutter "hacking is bullshit" and walk out of the room. My colleague, Craig, and I have now taken to calling arbitrary things "bullshit." Usually hacking, but often computers, programming, people, or D-Link routers.
Yet, we are driven to hack. We are driven to further the study of vulnerability research, to keep moving the ball down the field. The exchange of hours of frustration for minutes of victory is worth it. It's worth it because the next time we solve a similar problem, it takes a few hours rather than hundreds. It's worth it because the victory is amazing. It's worth it because the euphoria is like nothing else.
It's worth it, but let's be clear: hacking is bullshit.
I wanted to capture the irony of the frustration-to-victory inequity of hacking, so I made a T-shirt on Zazzle called "Hacking is Bullshit."
Here are some pictures:
I made it for myself, but if you'd like one of your own, here's a link that sends me a little kickback for beer.
Cheers and keep up the hacking. It's worth it.
Sunday, February 10, 2013
Friday, February 01, 2013
DLink DIR-815 UPnP Command Injection
With all the excitement regarding UPnP vulnerabilities lately, I though I'd write up this one I found a few weeks back. I had kind of forgotten about it. But it's pretty straight forward, and kind of fun, so here it is.
In Tactical Network Solutions' Intro to Embedded Device Exploitation class, we use the D-Link DIR-815 for the practical exercises since there are tons of great 0-days for the students to find. The last time we taught the class, I thought I'd try my hand at finding a new one. Twenty minutes in, voila! Command injection in a single multicast packet!
The DIR-815 has a single binary executable, /htdocs/cgibin, that is responsible for handling most, if not all, HTTP requests. I found a symlink to cgibin called 'ssdpcgi':
If we disassemble cgibin and look at ssdpcgi_main(), we see it executing a shell script called "/etc/scripts/upnp/M-SEARCH.sh".
So let's look at M-SEARCH.sh:
The contents of the M-SEARCH packet get turned into shell arguments. If we can get one of the arguments to be a string inside backticks, the string gets executed by system()'s 'sh -c' and its output gets handed to M-SEARCH.sh as arguments.
So what if we send an M-SEARCH packet with the ST: field containing the string `reboot`?
If we send that packet to the 239.255.255.250 multicast address, on UDP port 1900, our D-Link router reboots! Nice!
But rebooting routers is bullshit. Root or it didn't happen, right? Okay, no problem. D-Link routers generally come with a telnet server onboard, so lets use the command injection to fire it up:
Ownage in a single multicast packet. Not bad for 20 minutes of strings analysis and a few lines of Python.
Here's some proof-of-concept python code to try out.
In Tactical Network Solutions' Intro to Embedded Device Exploitation class, we use the D-Link DIR-815 for the practical exercises since there are tons of great 0-days for the students to find. The last time we taught the class, I thought I'd try my hand at finding a new one. Twenty minutes in, voila! Command injection in a single multicast packet!
The DIR-815 has a single binary executable, /htdocs/cgibin, that is responsible for handling most, if not all, HTTP requests. I found a symlink to cgibin called 'ssdpcgi':
zach@endor: dir-815-reva1/v1.00/squashfs-root/htdocs (0) $ ls -l upnp/ssdpcgi lrwxrwxrwx 1 zach wheel 14 Jan 9 13:43 upnp/ssdpcgi -> /htdocs/cgibin
If we disassemble cgibin and look at ssdpcgi_main(), we see it executing a shell script called "/etc/scripts/upnp/M-SEARCH.sh".
A shell script gets excecuted with the contents of the ST field as an argument. |
The contents of the M-SEARCH packet get turned into shell arguments. If we can get one of the arguments to be a string inside backticks, the string gets executed by system()'s 'sh -c' and its output gets handed to M-SEARCH.sh as arguments.
So what if we send an M-SEARCH packet with the ST: field containing the string `reboot`?
M-SEARCH * HTTP/1.1 HOST:239.255.255.250:1900 ST:uuid:`reboot` MX:2 MAN:"ssdp:discover"
If we send that packet to the 239.255.255.250 multicast address, on UDP port 1900, our D-Link router reboots! Nice!
But rebooting routers is bullshit. Root or it didn't happen, right? Okay, no problem. D-Link routers generally come with a telnet server onboard, so lets use the command injection to fire it up:
Getting root via command injection on the D-Link DIR-815 wireless router |
Here's some proof-of-concept python code to try out.