Challenge : Damn Vulnerable IoT Device
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.
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...
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 name | Full name | We have it |
---|---|---|---|
1 | DCD | Data Carrier Detect | No |
2 | RxD | Received Data | Yes |
3 | TxD | Transmitted Data | Yes |
4 | DTR | Data Terminal Ready | Yes |
5 | SG | Signal Ground | No |
6 | DSR | Data Set Ready | No |
7 | RTS | Request To Send | No |
8 | CTS | Clear To Send | On usb only |
9 | RI | Ring Indicator | No |
CASE | FG | Frame Ground | No |
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 |
| | |
+------------+-----------+
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.
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.
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.
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
commandThe 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 ~?
.
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
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
:flash ROM
of the device.r
.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.
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 !