Hardware 1 - Serial

Challenge Description

We managed to eavesdrop on the serial communication of an Arduino-based door locks debugging interface. Can you find the password?

  • This challenge has a downloadable part.

Steps

Unzip challenge files:

unzip hw_serial.zip

We get a file signal.txt, which is the debugging dump of the arduino-based door lock. As we get from the challenge description the file will contain the Serial binary data that we have received from the Arduino. The serial protocol used is UART.

If we cat its output:

cat signal.txt

111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111101010001010110000101011001010101100001010110111101010101100101100110010010011001010001100100010110010100011001011111010101100011010000011001010110110101011011010101011101001110110101000110010110001101000101100101110110010100011001000001100100111011010111110101010001100101010110010111110101011001100100110111010110011001001001100101001111010111011101000010110101100110010010011001011001100101111101010100011001001110110101111101010110011001010110110100001110010110011001000100110100010011010110011001000100110101000010010100001001000100110101010110010010011001010111110111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

The UART is a Universal Asynchronous Receiver-Transmitter. UART data is transmitted by a serial code in the following format.

High Waiting (1) bits - Start Bit (0) - 8 data bits (--------) - Stop Bit (1)

As we noticed in the beginning we have a lot of 1’s, which means there is no data transmission and when the first 0 is found it must be the Start Bit, so the next 8 bits are the Data Bits and then it continues with 1’s until the next 0 is found.

It is a very easy protocol and we can separete the given binary data with the scheme we just explained:

111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
10 10100010 10 11000010 10 11001010 10 11000010 10 11011110 10 10101100 10 11001100 10 01001100 10 10001100 10 00101100 10 10001100 10 11111010 10 11000110 10 00001100 10 10110110 10 10110110 10 10101110 10 01110110 10 10001100 10 11000110 10 00101100 10 11101100 10 10001100 10 00001100 10 01110110 10 11111010 10 10001100 10 10101100 10 11111010 10 11001100 10 01101110 10 11001100 10 01001100 10 10011110 10 11101110 10 00010110 10 11001100 10 01001100 10 11001100 10 11111010 10 10001100 10 01110110 10 11111010 10 11001100 10 10110110 10 00011100 10 11001100 10 00100110 10 00100110 10 11001100 10 00100110 10 10000100 10 10000100 10 00100110 10 10101100 10 01001100 10 10111110
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

If we delete the start-stop bits, we have the raw data bytes:

10100010  11000010  11001010  11000010  11011110  10101100  11001100  01001100  10001100  00101100  10001100  11111010  11000110  00001100  10110110  10110110  10101110  01110110  10001100  11000110  00101100  11101100  10001100  00001100  01110110  11111010  10001100  10101100  11111010  11001100  01101110  11001100  01001100  10011110  11101110  00010110  11001100  01001100  11001100  11111010  10001100  01110110  11111010  11001100  10110110  00011100  11001100  00100110  00100110  11001100  00100110  10000100  10000100  00100110  10101100  01001100  10111110

But these are the data that are being transmitted so we need to reverse each byte because we are receiving them with the opposite order:

01000101 01000011 01010011 01000011 01111011 00110101 00110011 00110010 00110001 00110100 00110001 01011111 01100011 00110000 01101101 01101101 01110101 01101110 00110001 01100011 00110100 00110111 00110001 00110000 01101110 01011111 00110001 00110101 01011111 00110011 01110110 00110011 00110010 01111001 01110111 01101000 00110011 00110010 00110011 01011111 00110001 01101110 01011111 00110011 01101101 00111000 00110011 01100100 01100100 00110011 01100100 00100001 00100001 01100100 00110101 00110010 01111101

These raw bytes can now by converted to ASCII characters, using like an online tool from Rapid Tables, and we get:

ECSC{532141_c0mmun1c4710n_15_3v32ywh323_1n_3m83dd3d!!d52}

This is our flag.

Of course this task can be automated with a python script:

#!/usr/bin/python3

import sys
import binascii

if __name__ == '__main__':

    if len(sys.argv) < 2:
        print('Usage:', sys.argv[0],'<singal.txt>')
        exit(1)

    file_name = sys.argv[1]

    ## Read bits to string
    with open(file_name, 'r') as fp:
        content = fp.read()

    print('----- Raw data: -----')
    print(content)

    flag_iter = []
    uart_bytes = []
    for i, bit in enumerate(content):
        if (i in flag_iter):
            continue
        ## Check change of start and stop bit
        if (content[i-1] == '1') and (content[i] == '0'):
            ## Keep 8 data bits
            data_bits = content[i+1:i+9]
            # print(data_bits)
            uart_bytes.append(data_bits)
            flag_iter = list(range(i+1, i+9))
            # print(flag_iter)

    print('----- UART Bytes: -----')
    print(' '.join(uart_bytes))


    uart_bytes_rev = []
    for byte in uart_bytes:
        ## Reverse each byte
        uart_bytes_rev.append(byte[::-1])

    print('----- UART Bytes Reversed: -----')
    print(' '.join(uart_bytes_rev))

    flag = []
    for byte in uart_bytes_rev:
        ascii_num = int(byte, 2)
        acii_char = chr(ascii_num)
        flag.append(acii_char)

    print('----- UART Bytes ASCII: -----')
    print(''.join(flag))

And we can run :

python3 rev_signal.py signal.txt

Flag

Flag: ECSC{532141_c0mmun1c4710n_15_3v32ywh323_1n_3m83dd3d!!d52}

Resources