Having root is fun, talking to the UART is better.
Opening up the device was quite a hassle, there are two screws and the rest is fastened using plastic clips. I had to break a couple of clips when I opened the device. I honestly don’t see how you can open the device without breaking these clips.
There are 4 solder pointers on the board with a label “J2”, I guessed this was where you can connect the UART. And it turns out I was right. I soldered a 4-pin header on the board to make it easier to connect a serial cable.
I first tried this with an Adafruit 4 Pin Cable (PL2303). But sadly, I blew it up connecting it to the 3.3v pin (or, at least, I think that is wat caused it.)
After which I tried, what I believe originally was a Nokia phone connector cable which can be (ab)used as a 3.3v serial cable. And yay! It worked.
This is the pin-out on the board. Pin 1 is the pin with the white dash above it.
Pin Function 1 Probably 3.3v. 2 Ground (Connected to ground) 3 TX (Connected to RX) 4 RX (Connected to TX)
The Nokia phone connector
Cable Function Black Ground White RX Blue TX
The baudrate is: 115200
You can find a dump of the successful UART connection here. Note that I entered the password wrong twice.
I was playing around with the new wireless router I bought and wondered if the input to the ping command was escaped properly. It wasn’t.
On Unix systems, in order to send a ICMP echo request you’ll need root permissions, or at least special permissions. Ping is usually implemented by setting the setuid bit on the ping(8) executable.
Because root permissions are required to send a ICMP echo request, the easiest way to implement ping in a web interface is to call ping(8) with the proper arguments, and parsing the result.
The way the fols at TP-LINK implemented this is by using system(3) or similar, and just directly pass “ping $userdata” to a shell. Without ever validating, or escaping $userdata.
How to exploit this?
Using the TP-LINK AC750 web interface the output data of the ping functionality isn’t (directly) sent back to the web interface. What you get as a result is either, unknown host, no response, or ICMP echo replies.
The first experiment is this input:
This probably invokes something like:
$ ping "$(echo 127.0.0.1)"
which is translated by the shell to.
$ ping 127.0.0.1
Using this input we can verify the input data isn’t escaped. If it returns ICMP echo responses, it worked. If it didn’t, they probably fixed the bug.
Obviously, we want a shell. I played around a bit with various commands to find out which commands we have at our disposal. (What I did is, I dumped a directory listing, and the output of various commands to the USB drive which I attached to the router. )
I found out there is a telnetd(8) daemon available. Also, by default this telnetd(8) server already runs with Cisco IOS-like shell, which allows you to change the same settings as the web interface, but with horror of the IOS shell.
So, first, we should kill that shell. We can do that with the following input.
"$(killall telnetd > /dev/null && echo 127.0.0.1)"
Then we start telnetd again, now with the bourne shell.
"$(/usr/sbin/telnetd -l /bin/sh > /dev/null && echo 127.0.0.1)"
Now if you open a telnet session with the router, you’ve got a root shell :)
How bad is this?
I think it’s a good idea that customers get full access to the appliances they purchase. So, from that perspective I think this is more a feature than a bug.
If you want to give users web access to the router, but not root access, this is a bug. But I doubt there are many users who want this.
What is bad about this, is the fact that the webserver is run as a superuser. Worse, all processes are run as superuser.
I’ve been trying to figure out the protocol for the Abbott Freestyle product line. I made a protocol description which can be found here.
If you’re looking for the description for the Abbott Xceed product line, Chris Ridd made an awesome description which can be found here. He also made an implementation in Objective C, but I haven’t found time to test that.
Abbott sells an adapter cable which uses the TI 3410 chipset. This chipset is supported by most modern operating systems, however not all include the Abbott vendor id/product id (0x1a61, 0x3410 respectively). Currently it should work by default in Windows XP using the driver Abbott supplied, and in OpenBSD since this commit. Getting it working with other operating systems should be trivial.
subscribe via RSS