This post spoils a CTF challenge … Don’t read if you want to try it !

ECW (European Cyber Week) is a Jeopardy student CTF challenge. It is organized by Thales, Airbus and the Bretagne region. I had a great time solving these challenges, especially reverse and pwn ones. Hurry to hand over this !

[+] Presentation

You are a member of the demining team. A highly critical mission just emerged. A bus is stopped, and an anonymous call denounced the presence of a bomb in the vehicle. The antiterrorist cell managed to get the bomb’s plans and it’s firmware:

Will you be up to scratch the plans of the terrorists? Go for it because the clock is running !!! Tic tac Tic tac …

To validate the challenge enter the answer with the following format ECW{1-5-5-4 …}

[+] Recon

By reading the PCB plan, we known that the main microcontroller is a STM32, which uses an LQFP48 chip.
The buttons used here are on pins 41, 42, 43, 45 and 46.

The documentation tells us that this is an ARM microcontroller, we can find it’s memory mappings and schematics here (page 26 and 34) :
- I/O pins from 0x40010800 to 0x40011c00
- ROM memory at 0x8000000
- RAM memory at 0x20000000
- Pins 41, 42, 43, 44, 45 and 46 correspond to Port B Pins 5, 6, 7, 8 and 9


The reset function (which is executed at every restart) can be located at 0x8000010.

reset func

This function initializes the stack pointer (SP register) and calls the main function (which is the main loop of the firmware).

Let’s look at it !

[+] Reversing

The main function can be split in two parts : the pins initialization (set every pin to input or output mode for example) and the real buttons combination’s check !

The first part is not really interesting for us except three details : 3 dwords are pushed to the stack (located at 0x8000198, 0x8000194, 0x800019c), r5 register is set to 0 and r7 is set to the stack pointer after pushing those 3 dwords.

init func

Let’s have a look at the second one.

main func

r1 contains the address 0x40010c08. This address corresponds to the inputs pins on Port B, so the firmware is basically reading which buttons are pushed or not right here.
All pin’s value are stored in r2, and then each pin value is extracted with an AND operation :
- And 0x20 => pin 5
- And 0x40 => pin 6
- And 0x80 => pin 7
- And 0x100 => pin 8
- And 0x200 => pin 9

Each pin is associated with a value (1, 2, 3, 4, 5) which is then xored with 0x2a.
The result is then comparated to a value on stack at index r5. If the comparison is validated, r5 is increased by 1.
Finally, if r5 is equals to 0xc, the main loop ends and the bombs is disarmed …

So we just need to extract thoses values from the firmware, xor them with 0x2a and we will obtain the button sequence to push !

Here’s the final script :


sequence = [0x2f, 0x2e, 0x28, 0x2f, 0x2e, 0x2e, 0x2e, 0x2b, 0x2b, 0x2f, 0x28, 0x2e]
flag = "ECW{"

for value in sequence:
	flag += ("%d-" % (value ^ 0x2a))
flag = flag[:-1] + "}"
print("Flag : %s" % flag)

Flag is : ECW{5-4-2-5-4-4-4-1-1-5-2-4}

[+] Bye

Feel free to tell me what you think about this post :)