Hardcoded password

19 March 2019

Challenge : Damn Vulnerable IoT Device

Tools

We are given the DVID card and asked to enter the right password over a serial communication. We also have a USB UART to establish the serial communication. And finally we have a USB ASP to flash the firmware and extract it.

Serial communication

Definition

Since I have approximately zero knowledge of electronics, I am asking myself right now, what exactly defines a serial communication ?

After reading an introduction from contec.com I learnt that serial communication is a communication method that uses one or two transmission lines to send and receive data, and that data is continuously sent and received one bit at a time.

There are multiple serial communication standards which are either simplex, multiplex, full-duplex, half-duplex, single-ended, differential...

RS-232C

The most widely used standard is RS-232C. The description of each PIN of this standard can be found below. I also marked the pins available on the board and the given USB that should be used to establish the serial communication.

Pin No.Signal nameFull nameWe have it
1DCDData Carrier DetectNo
2RxDReceived DataYes
3TxDTransmitted DataYes
4DTRData Terminal ReadyYes
5SGSignal GroundNo
6DSRData Set ReadyNo
7RTSRequest To SendNo
8CTSClear To SendOn usb only
9RIRing IndicatorNo
CASEFGFrame GroundNo

UART

Now we have an idea of what the pins are used for but we are still lacking the understanding of the protocol.

A good introduction is a tutorial available on sparkfun.com

There we learn that embedded systems usually communicate at a transistor-transistor logic level (TTL) which is slightly different from RS-232C. As it turns out, our USB UART is sold as a "USB To TTL Module".

We also learn that microcontrollers use UART (universal asynchronous receiver/transmitter) to convert their data on a parallel bus to and from a serial interface. Below is a simplified UART interface : the parallel on one end and the serial on the other.

                               UART
                     +------------+-----------+
                     |            |           |
         +-----------+D0          |           |
         |  +--------|D1          |           |
         |  |  +-----|D2          |         RX+<------+
Data Bus |  |  |  +--+D3          |           |
  +---------------+  |            |         TX+------->
         |  |  |  +--+D4          |           |
         |  |  +-----|D5          |           |
         |  +--------|D6          |           |
         +-----------+D7          |           |
                     |            |           |
                     |            |           |
   Control I/O  +----+R/W         |           |
  +------------------|CLK         |           |
                +----+INT         |           |
                     |            |           |
                     |            |           |
                     |            |           |
                     |            |           |
                     |  Parallel  |   Serial  |
                     |            |           |
                     +------------+-----------+

ATmega328p and UART

We know that our board uses an ATmega328p, and we can see that the board has a component labelled UART.

If we take a look at the ATmega328p pin mapping here is what we get (limited to the interesting parts):

       +----------+
       |   `--´   |
       |          |
       |          |
RESET  |1       28|
  RXD  |2       27|
  TXD  |3       26|
 INT0  |4       25|
 INT1  |5       24|
   T0  |6       23|
  VCC  |7       22| GND
  GND  |8       21|
       |9       20|
       |10      19|
       |11      18|
       |12      17|
       |13      16|
       |14      15|
       |          |
       |          |
       +----------+

Now if we look at the board and the circuits on it we can draw the following connections :

       UART                     +----------+
                                |   `--´   |
+----------+                    |          |
|          |                    |          |
|          |                    |1       28|
|       RX +--------------------+2       27|
|       TX +--------------------+3       26|
|          |                    |4       25|
|          |                    |5       24|
|          |                    |6       23|
|          |                    |7       22|
|          |                    |8       21|
|          |                    |9       20|
|          |                    |10      19|
|          |                    |11      18|
|          |                    |12      17|
|          |                    |13      16|
+----------+                    |14      15|
                                |          |
                                |          |
                                +----------+

I could not clearly see the GND and VCC connections with the ATmega328p already soldered on, but I have to assume that the UART's VCC and GND are connected to the ATmega328p VCC and GND respectively.

Now we know that our ATmega328p already includes a UART and the board gives us an easy access.

VCC and GND

Looking up for "what is VCC" we understand that VCC stands for Voltage Common Collector.

VCC is the power supply pin. GND is the ground.

We know have enough knowledge to connect the given USB to the board and not blow anything up.

Board connection

Once we have connected the board to our computer, the screen lights up and a message appears : A useful information is hardcoded, Find it to unlock.

Since we have connected the board to our computer through a serial port, we should be able to send it data; however we won't be able to receive data from it as the board has not been configured to send data.

A quick DDG search for linux communicate over serial port gives us a tutorial explaining how we can do this.

Finding the board name

We connect the USB UART to our computer and use dmesg to get some info about what we just connected :

[166627.924066] usb 1-8: new full-speed USB device number 23 using xhci_hcd
[166628.073498] usb 1-8: New USB device found, idVendor=1a86, idProduct=7523
[166628.073505] usb 1-8: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[166628.073509] usb 1-8: Product: USB2.0-Serial
[166628.074457] ch341 1-8:1.0: ch341-uart converter detected
[166628.075089] usb 1-8: ch341-uart converter now attached to ttyUSB0

In the tutorial we found we are told to use dmesg | egrep 'serial|ttyS to retrieve the information about our just connected serial port; however this won't work in our case since the USB device is clearly attached to ttyUSB0 as mentionned in the logs.

cu command

The cu command acts as a dial in terminal. Once installed, we add ourselves to the dialout group in order to use the command without sudo.

sudo usermod -aG dialout braincoke

There is a complete guide explaining serial communication and the tools written by David S.Lawyer. And a tutorial about cu can be found here.

To initiate a serial communication we use the command cu -l /dev/ttyUSB0 -s <baud_rate>.

We don't have the baud rate so we have to try multiple one until we find the right one. However the most used baud rate in microcontroller is 9600. When we use 9600 and we type in some random password, the board reacts and the screen display indicates that we have the wrong password.

cu -l /dev/ttyUSB0 -s 9600

To close a connection we use : ~. To list all commands ~?.

screen

We can also use screen to connect to the board :

screen /dev/ttyS0 9600

To see the processes using /dev/ttyUSB0 we use:

sudo lsof /dev/ttyUSB0

This can come in handy when we get a message like [screen is terminating]. In this case we can kill the processes listed by lsof to solve the problem.

To kill a screen in the session :CTRL + A, k To get info in a screen session :CTRL + A, i

Extracting the firmware

The board told us that the password is hardcoded, so we should be able to find it in the firmware.

After some research, we find a post explaining how to update a firmware with a USBAsp.

Even though this was not exactly what we were looking for, we learn about the existence of the command avrdude.

After searching for "avrdude extract firmware" we learn that it is possible to extract firmware with avrdude.

The example given is the following :

avrdude -patmega328p -carduino -P/dev/cu.usbmodemFD121 -b115200 -U flash:r:"flash.bin":r

Where :

  • -p specifies the MCU connected to the programmer. We can show a list of valid part numbers with -C "?". Our part number is m328p since the ATmega is a 328p.
  • -c specifies the programmer-id. We can show a list of valid programmer-id with -c "?".
  • -P specifies the port to identify the device.
  • -b is the baud rate 9600 in our case.
  • -U describes the memory operation to do -U memtype:op:filename:format:
    • memtype : we target the flash ROM of the device.
    • op : we wish to read the flash ROM, so we will use r.
    • format : we will have to use r for raw binary.

Since we use a USBAsp to get the firmware we will have to use the programmer-id usbasp.

Now we have to find the port to use. When searching for more information in the avrdude man page we find the following mention of USBAsp :

The avrftdi, USBasp ISP and USBtinyISP adapters are also supported, provided avrdude has been compiled with libusb support. USBasp ISP and USBtinyISP both feature simple firmware-only USB implementations, running on an ATmega8 (or ATmega88), or ATtiny2313, respectively.

This documentation was way too cryptic for me to understand right away, so after researching some example usage of USBAsp and avrdude on the net I found out that you don't need to specify a port when using -c usbasp.

In the end our final command is :

avrdude -pm328p -cusbasp -b9600 -U flash:r:"flash.bin":r

We get the following output from the command

avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading flash memory:

Reading | ################################################## | 100% 16.63s

avrdude: writing output file "flash.bin"

avrdude: safemode: Fuses OK (E:FD, H:DA, L:FF)

avrdude done.  Thank you.

You're welcome avrdude.

Finding the hardcoded password

We just run strings flash.bin to list hardcoded strings in the binary :

[...]
APP@
APP@
1234
T01 Hard.Pass.
A useful information is hardcoded, Find it to unlock
Wrong password
Try again
Pass :
Well done ! Challenge unlocked
$N__O

Well 1234 certainly looks like a robust password, if we try it on the board we will see that we just solved the challenge !

Resources