UART Intro. and Sniffing UART with a Logic Analyzer

DISCLAIMER: EVERYTHING HERE WILL VOID YOUR PRODUCT WARRANTY

This is Part II in a series of blog posts I will be doing. The main tracking page is here.

Before we get into the process I used for sniffing a UART connection that ultimately lead to a root shell on a Home Automation hub we will go over UART quickly in an effort to understand what it is and what it is used for.

Overview of UART

UART stands for Universal Asynchronous Receiver (RX)/Transmitter (TX). It is a general-purpose component for transmitting and receiving data independent of the processor. Devices with asynchronous serial ports typically contain hardware UART. When devices communicate with each other via asynchronous communication they aren't relying on an external clock signal between the receiver or the transmitter. It uses a bitrate/baudrate.

Here is a picture of what UART PINs may look like on a PCB. Note the TX and RX PINs, which are used for communication. For this discussion we care more about the TX and RX PINs as that's what we will connecting to; however, we will also want to connect a ground wire to the ground PIN. We can ignore the Vcc pin for now.

Silvrback blog image

Some products that contain UART are SMART card readers, home automation hubs, etc. Lots and lots of electronic devices contain UART so it is important to get a good understanding of what it is and how it works.

We will be using a configuration as such = 8 bits with no parity and one stop bit (8-N-1). [StartBit][0][1][2][3][4][5][6][7][StopBit]

Keep in mind that when data is sent it is sent least significant bit (LBS) first.

So when you add up the 8 bits of data and the start and stop bits you will have a total of 10 bits. If we would have sent 7 bits instead of 8 bits of data we would need to set a parity bit and configure it to be even or odd (0 or 1).

I mentioned above about bit rate/baud rate. Baud rate translates to symbols per second. So assuming a baud rate of 9,600, we will transmit data at 9.6 kilobits per second.

When UART is idle (not transmitting data) it's set to "high", or logic 1 and when it sends it's first bit (start bit) it will be set to "low", or logic 0.

I learn better from pictures, so let's take a look at what this all looks like using one of the home automation systems I sniffed using my Saleae Logic 8.

You will see right before we hit the +0.5 ms marker the transmission is idle, or "high" (logic 1), which makes sense because nothing has crossed the wire yet and as a result it's idle, but then you see it drop into its start bit ("low"), and then 8 bits of data are sent. In this case, 0100 1010, which is hex 0x4A, or ASCII J. Notice the "bars' when the data is sent. When a 0 is sent the wave pattern is set to low, and when a 1 is sent it's set to high. Now you can more or less read the patterns even without some special software.

Silvrback blog image

Here is an example with the HEX and ASCII decoding turned on, which is normally what I do for ease of reading.

You will see here what actually crossed the wire was ASCII JFFS2, which is the magic header for journaling flash file system, which is used with flash memory devices. Now we know we are getting somewhere!

Silvrback blog image

Sniffing with a Logic Analyzer

So now that we have a quick overview of what UART is and how it is used I figured I would show you how I went about sniffing the data transmissions.

Below is an image of the home automation system PCB. With the information above you're able to easily spot the UART pins on this particular board (VCC, GRD, TX, RX). The next thing to do is see if they are hot, which I used a multimeter for. It's a bit hard to show you here how I went about doing this so hopefully you will have some idea how a multimeter works. It's pretty simple. If not, read SparkFun's how-to on multimeters.

Silvrback blog image

Now that we know the PINs are hot we can place our Logic Analyzer clamps on the PINs we want to monitor. In this case we want to hook up to GRD, TX and RX. More specifically TX, because TX is the transmit PIN so that's where the data will come from, but in either case we will connect to GRD, TX and RX. When you connect the logic analyzer it will look something like this.

Silvrback blog image

Once the logic analyzer pins are connected to the UART pins we can start our capture. Once we start the capture power on the home automation hub. Once it's finished you will see something like this:

Silvrback blog image

I call it (and i'm sure others do) the Wireshark for electronics. The screen output is really nice, but it doesn't scale. This particular Saleae product allows you to output the data in CSV format, which is nice, but it is also hard to read in its raw form. In it raw form it looks like this:

Time [s],Value,Parity Error,Framing Error 2.115247380000000,n,,
2.115420420000000,r,,
2.115593460000000,n,,
2.115766520000000,r,,
2.115939560000000,U,,
2.116112600000000,-,,
2.116285660000000,B,,
2.116458700000000,o,,
2.116631740000000,o,,
2.116804800000000,t,,
2.116977840000000,' ',,

In this case I really only care about the value data and after seeing this output I know I needed something better so I wrote a quick python script to parse the data and make it more readable.

import sys  
with open(sys.argv[1], 'r') as f:  
    value_list = []
    next(f)
    for line in f:
        initial_cleanse = line.split(',')[1].strip()
        value_list.append(initial_cleanse)
    final_cleanse = " ".join(value_list).replace(" ", '').replace("nr", "n").replace("n", "n").replace("r", "").replace("''", ' ')
print(final_cleanse)  

And here is the output from saleaeparse.py. As you can see it is much easier to read. It's more or less the same as you would see if you were to connect to the serial port and watch the screen while spits out all the text.

python saleaeparse.py homehub.txt |head -20

U-Boot 1.1.3 (Jan 19 2012 - 17:57:52) Board: Ralink APSoC DRAM:
Return Real size =67108864 !!
64 MB
relocate_code Pointer at: 83fa8000
Ralink UBoot Version: 3.4.0.4
Model:
ASIC 3883_MP (MAC to 100SW Mode)
DRAM component: 512 Mbits DDRCOMMA width 16
DRAM bus: 16 bit
Total memory: 64 MBytes
Flash component: NAND Flash
Date:Jan 19 2012 Time:17:57:52

Much easier on the eyes, yeah? You can download the code from my GitHub account.

Although not pasted above, while reviewing the full output of the 90 second collection I saw the following message, "Press the [f] key and hit [enter] to enter failsafe mode".

This is interesting, so let's take a deeper look using another piece of equipment called Shikra. This will allow me to speak with various low(er) level data interfaces. In this case we will be interfacing with UART as we already discussed.

Connecting to the Home Automation Hub's UART PINs

The Shikra is the device on the right hand side plugged into my USB port.

Pins layout

  • Shikra: TX ---connected_to---> RX of Home Automation Hub
  • Shikra: RX ---connected_to---> TX of Home Automation Hub
  • Shikra: GRD --connected_to---> GRD of Home Automation Hub

Silvrback blog image

Now that the pins are hooked up properly we can attempt to connect to the home automation hub through Shikra. To do this we will use the screen command, but before we can do that we need to know the path of our Shikra.

You can accomplish this via the following:

ls /dev/serial (on Mac)

  • /dev/cu.usbserial-141
  • /dev/tty.usbserial-141

python -m serial.tools.list_ports

  • /dev/cu.Bluetooth-Incoming-Port
  • /dev/cu.Bluetooth-Modem
  • /dev/cu.usbserial-141
  • 3 ports found

On Linux it will look like this:
* /dev/ttyUSB0

If you go the python route you will need to install pyserial via pip install pyserial

Now that we know our serial device information we can connect.

screen /dev/ttyUSB0 57600

Once we kick off the command we will turn on the home automation hub and once you start seeing a bunch of text we can hit either f + enter or simply hit enter a few times. Either one will drop us into root, although there are a few additional commands in failsafe mode.

Root Please?

So if everything worked as discussed we should now have our root shell and we can pretty much do anything we want at this point. We can dump memory, image mounted drives, grab the firmware, etc.

If you decided to go into failsafe mode your root prompt will look something like this: root@(none):/#

If you simply hit enter a few times your root shell will look like this.

enterBusyBox v1.17.3 (2012-01-09 12:40:42 PST) built-in shell (ash) root@redacted:/#

The redacted parts show the serial number of my device, which I don't want published. I don't feel like buying a new one because someone locks me out.

Summary

So there we have it. Overview of UART, how to connect to the pins, and ultimately how we got root. I guess you could say, I got lucky, but I have to assume a lot of consumer electronics are configured in a similar fashion and you don't know what you don't know until you do it for yourself.

Again, my main point of this series was to look at the forensic evidence more than the hacking. In the next blog I will look at the forensics side of gaining root so this device and see if we can uncover any forensic evidence from the device.

It can be an expensive learning experience, but so far this is some really cool work. I've learned a lot just in the few days playing with this. Now I just need to figure out how I can do this day-in-day-out and get paid for it! Haha. #InTime... #InTime...

I've also added some more resource links to my into post so make sure to keep an eye on the original post of this series for the latest sites I found helpful.

References: How does UART Work Wikipedia - UART