Hardcoded password
Challenge
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
What is 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…
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 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 |
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 |
| | |
+------------+-----------+
Erwan Dano
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 ism328p
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.
- memtype : we target the
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 !
r2
If we have a sadomasochism fetish, we can use radare2 to examine the extracted binary.
We will have to specify the architecture to radare with the -a
option :
r2 -a avr flash.bin
-- Control the height of the terminal on serial consoles with e scr.height
[0x00000a8e]>
We start an analysis with aaa
:
[0x00000a8e]> aaa
[Cannot find function 'entry0' at 0x00000a8e entry0 (aa)
[x] Analyze all flags starting with sym. and entry0 (aa)
[ ]
[Value from 0x00000000 to 0x00008000
aav: 0x00000000-0x00008000 in 0x0-0x8000
[SPM: I dont know what to do with SPMCSR 783318e0.
SPM: I dont know what to do with SPMCSR 783318e0.
SPM: I dont know what to do with SPMCSR 783318e0.
SPM: I dont know what to do with SPMCSR 783318e0.
SPM: I dont know what to do with SPMCSR 783318e0.
[x] Analyze function calls (aac)
[SPM: I dont know what to do with SPMCSR 783318b0.es (aar)
SPM: I dont know what to do with SPMCSR 783318b0.
SPM: I dont know what to do with SPMCSR 783318b0.
SPM: I dont know what to do with SPMCSR 783318b0.
SPM: I dont know what to do with SPMCSR 783318b0.
[x] Analyze len bytes of instructions for references (aar)
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
As we can see radare has some trouble analysing the binary.
Anyway, we start looking for the string “Wrong” to see where it is placed in the binary and have a better understanding of its structure.
[0x00000a8e]> / Wrong
Searching 5 bytes in [0x0-0x8000]
hits: 1
0x00003e02 hit0_0 .t to unlock 50Wrong passwordTry ag.
[0x00000a8e]>
The string “Wrong” is found at 0x3e02
. Let’s have a look at the data around
this place. The following command displays 400 words starting at 0x3e02-200
[0x00000a8e]> pxw 400 @ 0x3e02-200
0x00003d3a 0xe0d5e4c6 0x01fec004 0x1c8a940e 0x34c79621 ............!..4
0x00003d4a 0xf7c907d1 0xcfff94f8 0xb0000001 0x00008003 ................
0x00003d5a 0x05000000 0x9c057206 0xcd065205 0xbf05ab05 .....r...R......
0x00003d6a 0x00000005 0x320a5f00 0xf10a8e0a 0x160a2a08 ....._.2.....*..
0x00003d7a 0x000a070a 0x47000000 0x8e05720b 0x7e05710a .......G.r...q.~
0x00003d8a 0x1a08f106 0x0e08f209 0x21090209 0x3c08f109 ...........!...<
0x00003d9a 0xb80d7507 0x3a0afc0a 0xb0081d08 0x0d075107 .u.....:.....Q..
0x00003daa 0x3231000a 0x54003433 0x48203130 0x2e647261 ..1234.T01 Hard.
0x00003dba 0x73736150 0x2020202e 0x20002500 0x41003020 Pass. .%. 0.A
0x00003dca 0x65737520 0x206c7566 0x6f666e69 0x74616d72 useful informat
0x00003dda 0x206e6f69 0x68207369 0x63647261 0x6465646f ion is hardcoded
0x00003dea 0x6946202c 0x6920646e 0x6f742074 0x6c6e7520 , Find it to unl
0x00003dfa 0x006b636f 0x00303520 0x6e6f7257 0x61702067 ock. 50.Wrong pa
0x00003e0a 0x6f777373 0x540a6472 0x61207972 0x6e696167 ssword.Try again
0x00003e1a 0x73615000 0x203a2073 0x30303100 0x6c655700 .Pass : .100.Wel
0x00003e2a 0x6f64206c 0x2120656e 0x61684320 0x6e656c6c l done ! Challen
0x00003e3a 0x75206567 0x636f6c6e 0x0064656b 0xffffffff ge unlocked.....
0x00003e4a 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003e5a 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003e6a 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003e7a 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003e8a 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003e9a 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003eaa 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
0x00003eba 0xffffffff 0xffffffff 0xffffffff 0xffffffff ................
Note that we can display the result of our subtraction with ? <math expression>
.
Here we see that all the strings are bundled together. We find our password
1234
once again, but I’ll turn a blind eye on it for now.
Let’s try to find where the string “Wrong password” is called.
We know that the string is located at 0x3e02
:
[0x00003d3a]> ps @ 0x3e02
Wrong password
Try again