Practical Reverse Engineering Part 1 - Hunting for Debug Ports

  • Part 1: Hunting for Debug Ports
  • Part 2: Scouting the Firmware
  • Part 3: Following the Data
  • Part 4: Dumping the Flash
  • Part 5: Digging Through the Firmware

In this series of posts we’re gonna go through the process of Reverse Engineering a router. More specifically, a Huawei HG533.

Huawei HG533

At the earliest stages, this is the most basic kind of reverse engineering. We’re simple looking for a serial port that the engineers who designed the device left in the board for debug and -potentially- technical support purposes.

Even though I’ll be explaining the process using a router, it can be applied to tons of household embedded systems. From printers to IP cameras, if it’s mildly complex it’s quite likely to be running some form of linux. It will also probably have hidden debug ports like the ones we’re gonna be looking for in this post.

Finding the Serial Port

Most UART ports I’ve found in commercial products are between 4 and 6 pins, usually neatly aligned and sometimes marked in the PCB’s silkscreen somehow. They’re not for end users, so they almost never have pins or connectors attached.

After taking a quick look at the board, 2 sets of unused pads call my atention (they were unused before I soldered those pins in the picture, anyway):

Pic of the 2 Potential UART Ports

This device seems to have 2 different serial ports to communicate with 2 different Integrated Circuits (ICs). Based on the location on the board and following their traces we can figure out which one is connected to the main IC. That’s the most likely one to have juicy data.

In this case we’re simply gonna try connecting to both of them and find out what each of them has to offer.

Identifying Useless Pins

So we’ve found 2 rows of pins that -at first sight- could be UART ports. The first thing you wanna do is find out if any of those contacts is useless. There’s a very simple trick I use to help find useless pads: Flash a bright light from the backside of the PCB and look at it from directly above. This is what that looks like:

2nd Serial Port - No Headers

We can see if any of the layers of the PCB is making contact with the solder blob in the middle of the pad.

  1. Connected to something (we can see a trace “at 2 o’clock”)
  2. NOT CONNECTED
  3. 100% connected to a plane or thick trace. It’s almost certainly a power pin, either GND or Vcc
  4. Connections at all sides. This one is very likely to be the other power pin. There’s no reason for a data pin in a debug port to be connected to 4 different traces, but the pad being surrounded by a plane would explain those connections
  5. Connected to something

Soldering Pins for Easy Access to the Lines

In the picture above we can see both serial ports.

The pads in these ports are through-hole, but the holes themselves are filled in with blobs of very hard, very high melting point solder.

I tried soldering the pins over the pads, but the solder they used is not easy to work with. For the 2nd serial port I decided to drill through the solder blobs with a Dremel and a needle bit. That way we can pass the pins through the holes and solder them properly on the back of the PCB. It worked like a charm.

Use a Dremel to Drill Through the Solder Blobs

Identifying the Pinout

So we’ve got 2 connectors with only 3 useful pins each. We still haven’t verified the ports are operative or identified the serial protocol used by the device, but the number and arrangement of pins hint at UART.

Let’s review the UART protocol. There are 6 pin types in the spec:

  • Tx [Transmitting Pin. Connects to our Rx]
  • Rx [Receiving Pin. Connects to our Tx]
  • GND [Ground. Connects to our GND]
  • Vcc [The board’s power line. Usually 3.3V or 5V. DO NOT CONNECT]
  • CTS [Typically unused]
  • DTR [Typically unused]

We also know that according to the Standard, Tx and Rx are pulled up (set to 1) by default. The Transmitter of the line (Tx) is in charge of pulling it up, which means if it’s not connected the line’s voltage will float.

So let’s compile what we know and get to some conclusions:

  1. Only 3 pins in each header are likely to be connected to anything. Those must be Tx, Rx and GND
  2. Two pins look a lot like Vcc and GND
  3. One of them -Tx- will be pulled up by default and be transmitting data
  4. The 3rd of them, Rx, will be floating until we connect the other end of the line

That information seems enough to start trying different combinations with your UART-to-USB bridge, but randomly connecting pins you don’t understand is how you end up blowing shit up.

Let’s keep digging.

A multimeter or a logic analyser would be enough to figure out which pin is which, but if you want to understand what exactly is going on in each pin, nothing beats a half decent oscilloscope:

Channel1=Tx Channel2=Rx

After checking the pins out with an oscilloscope, this is what we can see in each of them:

  1. GND and Vcc verified - solid 3.3V and 0V in pins 2 and 3, as expected
  2. Tx verified - You can clearly see the device is sending information
  3. One of the pins floats at near-0V. This must be the device’s Rx, which is floating because we haven’t connected the other side yet.

So now we know which pin is which, but if we want to talk to the serial port we need to figure out its baudrate. We can find this with a simple protocol dump from a logic analyser. If you don’t have one, you’ll have to play “guess the baudrate” with a list of the most common ones until you get readable text through the serial port.

This is a dump from a logic analyser in which we’ve enabled protocol analysis and tried a few different baudrates. When we hit the right one, we start seeing readable text in the sniffed serial data (\n\r\n\rU-Boot 1.1.3 (Aug...)

Logic Protocol Analyser

Once we have both the pinout and baudrate, we’re ready to start communicating with the device:

Documented UART Pinouts

Connecting to the Serial Ports

Now that we’ve got all the info we need on the hardware side, it’s time to start talking to the device. Connect any UART to USB bridge you have around and start wandering around. This is my hardware setup to communicate with both serial ports at the same time and monitor one of the ports with an oscilloscope:

All Connected

And when we open a serial terminal in our computer to communicate with the device, the primary UART starts spitting out useful info. These are the commands I use to connect to each port as well as the first lines they send during the boot process:

Boot Sequence

Please choose operation:
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
 0

‘Command line interface’?? We’ve found our way into the system! When we press 4 we get a command line interface to interact with the device’s bootloader.

Furthermore, if we let the device start as the default 3, wait for it to finish booting up and press enter, we get the message Welcome to ATP Cli and a login prompt. If the devs had modified the password this step would be a bit of an issue, but it’s very common to find default credentials in embedded systems. After a few manual tries, the credentials admin:admin succeeded and I got access into the CLI:

-------------------------------
-----Welcome to ATP Cli------
-------------------------------

Login: admin
Password:    #Password is ‘admin'
ATP>shell

BusyBox vv1.9.1 (2013-08-29 11:15:00 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# ls
var   usr   tmp   sbin  proc  mnt   lib   init  etc   dev   bin

Running the shell command in ATP will take us directly into Linux’s CLI with root privileges :)

This router runs BusyBox, a linux-ish interface which I’ll talk about in more detail in the next post.

Next Steps

Now that we have access to the BusyBox CLI we can start nosing around the software. Depending on what device you’re reversing there could be plain text passwords, TLS certificates, useful algorithms, unsecured private APIs, etc. etc. etc.

In the next post we’ll focus on the software side of things. I’ll explain the differences between boot modes, how to dump memory, and other fun things you can do now that you’ve got direct access to the device’s firmware.

Thanks for reading! :)

Picking a Practice Lock in Slow Motion

Some time ago I recorded a slow motion clip of myself picking a cut-away lock. This kind of lock is used for lock picking practice, as it lets you see the pins and springs that make the lock work.

In this clip we can see the racking method. Racking a lock is the Rambo approach to non-destructive lock picking: You jam a racking pick into the lock (half diamond, snowman, saw… Pretty much any pick but a hook) and move it around; you play with the force applied in the tension wrench until all the pins lock in place.

This technique works beautifully here because we don’t have any security pins in the lock. Security pins usually require a more precise approach and need to be carefully picked pin by pin.

Slow motion

Regular speed

This is the same video at real time speed. As you can see, the whole process is pretty quick.

Explaining the video

Too much pressure in the tension wrench caused the first pin to overset (the lower part of the first pin got stuck between the cilinder -the piece that turns when the lock is opened- and the case).

After reducing the force applied in the wrench we can see the pin drop and lock into position. The lock is now ready to be opened.

Emulating a USB Mouse with mbed to Cheat at CookieClicker

Some time ago, I was testing mbed’s USBMouse and USBKeyboard, and used CookieClicker for the proof of concept.

The idea of these libraries is that the microcontroller will tell the computer “Hey, I’m a mouse” or “I’m a keyboard”, and we will program it to send the key presses or movements we want. This can be used for all kinds of reasons, such as security attacks: “Hey, I’m a keyboard. Launch the terminal, execute these commands, close the terminal.”, but it can also be used for fun. Here, the mbed will identify itself as a mouse, and send tons of left clicks without any delay between them.

Thanks to the mbed’s libraries, you don’t need to configure the low level stuff for USB communication, and the code is as simple as this:

#include "mbed.h"
#include "USBMouse.h" //The library to work as a mouse

USBMouse mouse; //Declare the object mouse
DigitalIn myInput(p5); //Set an input to control when to send clicks

int main() {
    myInput.mode(PullDown); //Internal pull-down in the input pin
    while (1) { //Forever:
        if(myInput.read()==1) //If the input button/switch is enabled
            mouse.click(MOUSE_LEFT); //click
    }
}

And here’s a video of the device in action:

Note: The computer does not actually lag like in the video. That was because of the screen-recording software.

For the sake of keeping this post short, I’m not going to post schematics, but it’s a really simple circuit: The switch is connected between the pin p5 and Vout, and the USB was an old USB cable cut in half, soldered to some header pins, and connected to the mbed’s USB pins as explained here.

In my quest for fun, I also wrote a program with the USBKeyboard library to send the key presses 0 to 9 time and time again. I replaced the switch with a button, started a StarCraft 2 game, created 10 random control groups, and kept the button pressed a few times during the beginning of the game. This way, we can inflate our APM (Actions Per Minute) automatically. Here is the result:

StarCraft sky high APM

I’ll have to try it again, pressing the button during much more time (That 736 APM is just the average APM for all the game), just to see how high it can go. Could it be possible to overflow a variable somewhere? We’ll see…

Non-Persistent XSS with a Curious Attack Vector

For those of you who don’t know it, “memondo network” is the spanish company behind a bunch of websites for memes, funny gifs, etc. And they have, according to alexa, a quite large amount of traffic (a couple of their sites being in the top 3000 and in the spanish top 200).

Well, a couple of days ago I found an XSS vulnerability in their search system with a curious attack vector, so let’s take a look at it:

The vulnerable pages were http://www.$(SITE).com/buscar/0/

When you tried to search something -“DEVDEV” in our example- this GET request was sent: http://www.cuantocabron.com/busqueda/0/devdev

XSS output vector

After playing a bit with the search parameter, the first output of the value (displayed to the user) seemed to be properly filtered, but the page navigation buttons -prev, next- were not, so we should be able to inject code there:

But that injection is tricky… The vulnerable parameter is a link, and it’s being processed by the server before echoing it to make it URL-friendly, which means that any space would become %20 and any slash would screw the attack up. That implies that you could get the code executed when you decoded those values manually in the source code, but that would not be a feasible attack.

As far as i got, I could not get a way to bypass that problem, so I had to think about a different attack vector… I couldn’t use tags with parameters (because of the space between the tag name and the first attribute) and I could not inject a script because of the slash in </script>, so…. What about adding attributes to the tag being injected?

It was dirty, it was anything but subtle and it required another step of social engineering, but it did work and it might fool someone out there. Here’s a quick example of how it could be done:

Shitty example of social engineering

And when the victim’s mouse hovers over the link…

Javascript successfully injected!

And that’s as far as I got. I did not wait to have anything prettier or better and just reported it like that. I sent the email yesterday at 22.12, they were very friendly about it and it had already been fixed by 12.00 today, so good job on their part :)

Creating a Drop-Down Menu with Qt 4.8

Using the widget QComboBox in Qt 4.8 is pretty easy, but the documentation can be a little bit confusing the first time you want to use it, so here is a quick example on how to use its basic features:

#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow *w = new MainWindow();
    w->show();
    
    return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QDialog>
#include <QComboBox>
#include <QLabel>
#include <QGridLayout>

class MainWindow : public QDialog
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);

private:
    QGridLayout *myGrid;

    //----<RELEVANT>-----
    QComboBox *myComboBox;
    QLabel *myLabel;
public slots:
    void mySlot(int idx);
    //----</RELEVANT>----

};
#endif // MAINWINDOW_H
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QDialog(parent)
{
    myGrid = new QGridLayout(this);
    myLabel = new QLabel("-");
    //<RELEVANT>
    myComboBox = new QComboBox();
        //we fill myComboBox with some stuff:
    myComboBox->addItem("AAA");
    myComboBox->addItem("BBB");
    myComboBox->addItem("CCC");
    myComboBox->addItem("DDD");
        //and we connect the signal to the appropiate slot:
    QObject::connect (myComboBox, SIGNAL(activated(int)), this, SLOT(mySlot(int)));
    //</RELEVANT>
    myGrid->addWidget(myComboBox, 0, 0, Qt::AlignLeft);
    myGrid->addWidget(myLabel, 1, 0, Qt::AlignLeft);
}

//The slot that will read our input and do something with it:
void MainWindow::mySlot (int idx)
{
    myLabel->setText(myComboBox->itemText(idx));
}

And now let’s take a look at how this simple example looks:

Default view Dropped menu 2nd option selected