Demystifying Hardware Security – Part II

By Alain Iamburg ·

Peering into the Wire

In Part I of this series, we covered the risk surrounding the unsafe implementation of embedded devices and the need for competent security professionals. Now let’s walk through the usage of a logic analyzer, an essential tool for capturing and analyzing digital traffic in embedded systems.

Logic analyzers are leveraged by engineers during the device development and debugging process, and they can also be used for reverse-engineering. I will be working with the Saleae Logic 16, but other logic analyzers can be used - provided they are capable of capturing at a suitable sample rate for the target signal. I will demonstrate the process using two examples: first with the PVED and then with an off-the-shelf IP camera.

Caution: Only use the Saleae to test devices which are isolated from AC MAINs. You may use it to test battery-powered devices or devices powered by two-prong, wall wart AC adapters. Read the User’s Manual prior to use.

Connect the Analyzer

Begin by connecting the Saleae hardware via USB and launching the Logic software. When the analyzer is detected, the green LED on the Saleae will begin pulsing.

Figure 1: Logic software in disconnected state

Set the Number of Channels

We will be sniffing traffic on the SPI (Serial Peripheral Interface) bus, which is widely deployed for a number of embedded applications. This bus operates over four wires comprised of the MOSI, MISO, SS and SCLK signals. It’s a good idea to select only the channels you will use so you get the highest possible sample rate. It will also make the resulting trace easier to read.

Under “Options,” select “Logic 16 Channels” then “Select custom channels.” Check channels 0-3 and click “Save.”

Figure 2: Selecting channels for capturing 4 signals simultaneously

Set the Voltage Range

Determine the voltage of the device by measuring with a multimeter and/or checking the chip’s datasheet for supported voltage ranges. The PVED contains a SPI EEPROM which is powered directly from the five volts provided by USB, so I chose “3.6V to 5.0V” under “Options” -> “Logic16 Input Voltages.”

Figure 3: With hardware connected, after setting channels and voltage

Connect Probes to the Device Under Test

We will be using the PVED for the first example. This device presents a login prompt over USB and compares login attempts against what is stored in the SPI memory chip. We will be capturing the resulting SPI traffic and analyzing it with the goal of intercepting information as it traverses the wire. The software and hardware of this device can be perused at the link below.

https://github.com/alainiamburg/pved

With the PVED unpowered connect the probe wire connector to the Saleae. On the opposite end, attach the micro grabbers to the desired pins.

Figure 4: Connecting probe wires to the Saleae

Ensure proper insertion of the connector. The gray ground wire is labeled “Ground” along the side, and it should be aligned with the Ground symbol on the Saleae. The ground wire connection is required as a reference point for the signals to be captured. If your final captured signals seem to be corrupted or missing, ensure the ground wire is tied to a common ground with the signal. Also ensure that adjacent probe leads are not touching each other and causing signals to short.

The diagrams below depict the pin-outs of the main microcontroller and the EEPROM chip. On the microcontroller, pin 8 (Ground) and pins 16-19 (SS, MOSI, MISO, SCK) will be probed for the SPI bus capture. These pins are connected to the EEPROM on its Vss, CS, SO, SI, and SCK pins, respectively. The microcontroller will send commands on the “MOSI – Master Out, Slave In” pin and read back data on the “MISO – Master In, Slave Out” pin.

It is important to take note of the colors of the probe wires and the corresponding colored channels in the Logic software. Channel 0 corresponds with the black probe wire, which is (somewhat confusingly) marked “1” on the Saleae as shown above. This is because hardware pin numbering conventions for chips and connectors start with the 1st pin, not the 0th pin. In general, the first pin of a device is also denoted by a small circle, arrow or other marking on the chip package as shown below.

Figure 5: CAT25128 SPI EEPROM pin out from datasheet

Figure 6: ATMEGA328P microcontroller pin out from datasheet

Figure 7: PVED internals with probes connected to SPI bus

Add a SPI Analyzer

The Saleae Logic software operates with the concept of modular protocol analyzers. These are overlaid onto channels to decode the underlying protocol-specific signals, and they can be thought of as analogous to the dissectors in the popular Wireshark network protocol analyzer. A collection of analyzers covering the most popular embedded protocols are already included in the product, and additional analyzers can be imported to cover other protocols.

If you reverse-engineer an unknown protocol you can use the Saleae SDK to write a protocol analyzer for convenient decoding. Adding the analyzer can be done before or after taking a capture. In this case, we will add it first because we will be capturing a known signal.

To analyze and decode SPI (or other digital) traffic, the capture/analyzer software must know which component of the signal is tied to which wire (in this case referred to as a channel). I chose to use the black wire for the Clock component, the brown wire for the Enable component, the red wire for the MOSI component and the orange wire for the MISO component.

I attached these probe wires to the SCK, SS, MOSI and MISO pins on the microcontroller, respectively (shown above). The choice of which color wires you connect to which pins on the bus can be suited to your taste. The important thing is that you match the channel with the correct component of the SPI bus in the analyzer configuration as shown below.

Click “+” in the “Analyzers” dropdown box on the main Logic screen and select “SPI” from the list of available analyzers. Use the color code to help match channels to probe wires, and the rest of the settings should be left at their defaults.

Note that by default, bytes will be decoded as 8 bits per byte with the most significant bit first. These and other settings may require adjustment when analyzing custom systems and implementations. This is something to keep in mind if you feel the analyzer is decoding data incorrectly.

Figure 8: Configuring SPI analyzer settings

Figure 9: Renaming channel labels for SPI bus

Set the Sample Rate and the Number of Samples to Capture

In order to accurately capture signals, we must sample at a rate equal to or greater than the Nyquist Rate, which is two times the highest frequency of the signal being sampled. The CAT25128 EEPROM datasheet states the maximum speed for the chip’s SPI bus is 20 MHz (but in fact it is used at a lower speed by default in the PVED). In any case, the Logic 16 can handle this speed. A frequency counter can also be used to measure the signal directly.

We will be capturing ones and zeros, which are represented by alternating high/low voltage levels over time. These voltage levels must be sampled at an adequate rate to ensure the capture of each high/low transition. When assembled together, the high/low transitions are what make up the bits and bytes on the wire.

Since we know that we are trying to capture the bus traffic generated from a relatively slow keyboard login, we will set a trigger on one of the channels. This will allow the analyzer to automatically start the capture once the traffic starts.

An alternative would be to set a longer capture time and manually start the capture. For SPI, a transition on the ENABLE line (commonly known as “SS – Slave Select” or “CS – Chip Select”) indicates that a data transmission is about to occur. This scheme allows multiple devices or “slaves” to share the same data bus while avoiding bus contention.

The ENABLE line is generally “active low” meaning it idles at a high state and then goes low when a transfer is about to occur, so we will set a negative-edge trigger on the ENABLE channel. To do this, click the third button from the left which depicts a downward edge as shown below.

Figure 10: After adding a SPI analyzer and setting a negative-edge trigger

Capture and View

Click “Start Capture” to begin collecting samples. If you set a trigger, the software will wait for the trigger before starting the actual capture. Note that when initially capturing on unknown digital lines you would usually not set a trigger.

Figure 11: Waiting for the active-low Enable trigger

Once started, the capture will continue until either of the following conditions is true:

  • The selected number of samples has been collected.
  • The capture is stopped by the user.
  • A hardware overrun error occurs.

Sometimes during capture the Logic softwar­e will present an error reporting that it cannot keep up with the incoming data. This is an overrun and it can occur for a number of reasons such as USB/host latency/priority issues or insufficient hardware buffer size in the analyzer. If this is a problem for you, check the Logic User’s Guide under the section labeled “Data Integrity” for tips on resolving it.

Figure 12: Making a login attempt on the PVED

It is worth mentioning that the above ASCII login transaction can itself be captured using a logic analyzer. The Saleae comes with an Asynchronous Serial analyzer module which could be used on the RX and TX lines of the microcontroller (Pins 2 and 3).

Figure 13: SPI traffic generated from a single PVED login attempt

The above is the entirety of the SPI traffic generated by a single PVED login attempt. The PVED performs two separate memory reads demarcated by the ENABLE transitions. Zooming into the start of the capture (below), a READ (0x03) command is issued followed by a 16-bit address (0x0080). This matches the datasheet’s description of this chip’s READ functionality. Datasheets are invaluable for their useful information and they should be referenced frequently when working with integrated circuits. After the instruction is sent over MOSI, the EEPROM responds with memory contents over MISO.

Figure 14: CAT25128 EEPROM Instruction Set from datasheet

Figure 15: SPI read from address 0x0080 with clock speed measured at 2 MHz

Zooming back out a bit and switching to ASCII mode with CTRL+A shows the text “admin” followed by an MD5 hash. The second read returned “acidburn” followed by an MD5 hash.

Figure 16: Username and password hash being read from SPI EEPROM address 0x0080

Username/hash pairs were captured for users “admin” and “acidburn.” John easily cracks one password, but the admin password is stronger. Further investigation may be required to access the admin account. This will be covered in the next part of the series.

Figure 17: Cracking a password hash

Figure 18: Logging in

A Real-World Example

To help tie together the process I have just demonstrated, I will show it being applied to a TRENDnet TV-IP110 IP camera. Opening the case and inspecting the board reveals a W25Q32BV SPI EEPROM chip.

Figure 19: Winbond 25Q32BVSIG SPI EEPROM on TRENDnet TV-IP110 IP Camera

Since it is unknown when or what traffic might exist on the camera’s SPI bus, I took a long capture with no trigger. I started the capture, powered on the camera and collected the results.

Figure 20: Winbond W25Q32BV SPI EEPROM pin out from datasheet

Figure 21: Probing the Winbond EEPROM on the TRENDnet camera

Figure 22: Capture in progress

Figure 23: Results of a longer capture

Figure 24: Sequential memory read

Zooming in to the start of the SPI transactions, we can see the device issuing three sequential read instructions each returning 4 bytes of data, demarcated by the ENABLE state transitions. The trace output of a READ (0x03) command followed by a 24-bit address matches the description in the datasheet. The READ command is sent over MOSI and then the memory contents are returned over MISO.

Combining the above output from MISO, we see that the memory from address 0x000000 to 0x00000C contains 0x0BF000020000000000004021 (shown in decimal above). Note that SPI is able to operate in full-duplex, meaning data can be sent and received at the same time. In the case of this IP camera, it is operating in half-duplex. The zeros present on MISO during the read instruction are simply the absence of data.

The EEPROM datasheet also states that sequential memory reads can be accomplished by simply continuing to run the clock after any valid read instruction. In this case, the camera’s developers decided to issue consecutive 4-byte read instructions instead of a bulk continuous read. In fact, although many reads in this long capture were done on sequential addresses, many parts of the trace indicate reads of non-contiguous memory addresses. Sliding to a later point in the capture shows a read from address 0x000088 followed by a read from address 0x0004D0 as shown below in hex.

Figure 25: Non-sequential memory read

Export Data

Using the main export feature with CTRL+E to dump the MISO data is not feasible because it saves bytes based on each captured sample while we want to save bytes based on only those samples that coincide with the SPI clock.

Instead we can use the SPI analyzer’s CSV export feature by clicking the cog and then “Export.” In order to end up with a clean binary dump, we need to convert and fix up the data to discard the 4 garbage null bytes that are picked up on MISO during the time that MOSI is transmitting a READ instruction. The following one-liner will leave you with a binary file containing a concatenated blob of the memory that was read over the SPI bus.

printf $(cat camera_spi.csv |grep -v Time |cut -d',' -f4 |sed 's/0x/\\x/g' |awk 'A++ < 4 {next} B++ < 3 {print; next} {print; A=B=0}' |tr -d '\n') |dd of=camera_spi.bin bs=1 conv=notrunc

The screenshot below shows a portion of the resulting dumped memory reads.

Figure 26: A portion of the dumped EEPROM memory reads

Note the pattern and the “version v1.1g-1” ASCII string. Remember that this concatenated blob of data is made up of blocks of memory which are not all contiguous. As it turns out, most of the data is not human-readable, and automated file analysis tools failed to recognize known file signatures in the blob. The data might be compressed or encrypted. It might be an assortment of internal configuration values, or whatever else the developers had in mind.

The captured data totaled nearly 200KB whereas the memory chip has a 4MB capacity. Deeper investigation is required to determine the full contents of the EEPROM chip and this will be covered in the next part of the series.

Conclusion

By following this example, you will be prepared the next time you would like to passively intercept and decode the digital traffic inside an embedded device. From a security assessment standpoint, it is useful to analyze the traffic within a device to reverse-engineer protocols or intercept data to gain a deeper understanding of the device’s inner-workings. However, there are other powerful techniques that must also be considered.

A lot can be gained by actively communicating with integrated circuits. For example: reading or writing code/data in memory, issuing system commands or otherwise influencing the operation of system components.

In Part III, we will explore direct communications with embedded chips, including reading and writing SPI memory. I will be using the popular hardware-hacking multi-tool known as the Bus Pirate in its interactive and scripted modes. Stay tuned, friends…