Insomni’hack 2018 write-up – S3curLock level 1, 2 & 3

Challenge :


(photo from Tipi’Hack’s blog)

About the 3 hardware challenges, here is a full write-up. I’ve take extra time to even explain the 2 thirst level for n00b. If you are not in all those electronic stuff, you should have a look at this write-up.

First of all, the very first task is done at home before leaving: you need to pack everything you find useful for a CTF, and it looks like this:

A box full of EEPROM programmer, Arduino, STM32, logical analyzer, iron solder, resistor, LED, cables, multimeter etc. Even if the organizer give you all stuff you need, you are more comfortable with the tools you own/know. And more, you can have good surprise; we’ll see it later ;).

Level 1

For the first level, it asks you to locate the serial port and to hook your computer on the S3cure board. For this task, a simple USB <-> SERIAL module is enough.

For PIN hunting the process is always the same: you must identify the number of PIN you need to find and spot them on the board. The number of PIN depends on the bus or protocol you want to connect to. For a serial link, 3 PIN are needed, TX, RX and GROUND.

Here, you need to build something like a crossed Ethernet cable: TX-S3cureLock <-> RX-USB-serial and RX-S3cureLock <-> TX-USB-serial (and for sure, the GROUND).

The first thing to do is to locate the GROUND. When you hook electronic stuff to another electronic stuff, without connecting ground together, you risk burning some component :

Then, you need to find TX-S3cureLock. As it’s a 2 PIN connector, here you have 2 groups of 2 PIN. Only 4 possibilities, but you can guess more. 2 PIN are close to an EEPROM and are dedicated to it, so you need to try the other group of PIN first :

Connect the RX-USB-serial PIN and start a terminal at 9600 bauds (the most common), then RESET a few time the S3cureLock to see if something pop on screen. If there is garbage, you’re near done: you just need to guess the good baudrate. If nothing appears, change the PIN and start again to RESET the board.

When TX-S3cureLock is connected to RX-USB-serial, you just need to connect RX-S3cureLock to TX-USB-serial or you won’t be able to send byte to the S3cureLock. The RX-S3cureLock PIN is easy to spot; it’s the one beside the TX-S3cureLock.

When everything is wired as it should, in the terminal the flag pop:

Level 2

For the level 2 it was a little more complex: it asks you to guess the password. Under the terminal the S3cureLock display:

When you enter garbage and pushes ENTER, this string is displayed:

This means the CPU is reading the password from the external EEPROM each time you press ENTER.

The EEPROM is a 24LC02, this means an I2C EEPROM:

The next step is to connect a logical analyser to sniff the I2C traffic and reconstruct the password:

You have 2 possibilities, for PIN SCL and SDA (clock and data) but you don’t care at this moment. You run a capture, then sent it to an I2C decoder. You need to affect, IN THE SOFTWARE, each PIN to each signal. If it doesn’t decode fine, you just need to swap SDA & SCL and you’re done. No need to capture again.

When the decoding is done, you can read the flag :

Level 3, the serious stuff!

First, I start with a funny bug. The interface is protected by a password we just guessed at level 2. But no way to enter it, even if I was sure of the 20 bytes. Maybe a CR/LF or serial rate issue. So we shortcut the SDA + SCL pins together and supply no passwords, just ENTER. Then, after a timeout on I2C bus, the green LED light and the access is granted :). It’s the result of a strncmp(str1,str2,20) with 2 null strings. Never use strcmp() like functions !

Here is the display of the S3cureLock at the beginning of the level 3:

So, it’s asked to write a shellcode to dump the flag in flash. OK. A damn complex job!

But, wait, on the board there is another 4 pins connector we don’t have used yet:

A VCC, a GND and 2 pins in the middle are PA13 / PA14. This means just after RESET, it turns into SWDIO and SWCLK, so the ST-LINK bus is here. At the beginning I was telling you to be well prepared before a CTF. I have packed everything on the desk regarding STM32, this means I bring back my ST-LINK USB interface :).

As Joe Grand always say “people never set protection fuses”, let’s check it. And, bingo, it was the case. Balda’s bad :). 1 minute for extracting the firmware with the ST-Link interface:

Once the firmware is dumped, not luck with Radare2, it was impossible to have the strings analyzed and no way to XREF in the firmware. IDA was loading it fine, and it takes no long to spot in the firmware a dead-code with a XREF to the string “Oops ! I nearly forgot: The last flag is computed in this funct” with a XOR near the serialPrint() :


During a CTF, no rules, you MUST get the flag, the path doesn’t matter. That was the case here. But I must admit I was frustrated to not give a try to this blind ARM shellcode.

So here is my post-CTF solution, the Baldanos’s indeed the solution. And I must say I need to gain again the respect of Balda after this dirty trick :). As I already own an old revision of the S3curLock board, I’ve flash the dumped firmware and run the challenge again at home. Not matter of the EEprom content, because of the null-pointer’s bypass.

First thing to figure out is the stack/memory layout you’ll abuse. The challenge said it copy only 32 bytes at address 0x200008D8, and that’s all. When you enter 20 bytes, all is OK, no crash. With 21 bytes you crash the S3cureLock. So, layout is something like:

So we have only 20 bytes for the shellcode and two 32 bits arguments to pop to registers, for setup constants and address.

As dumping the firmware isn’t the easiest job, I’ll start with a simple shellcode: lightning the 2 on-board LEDs. As the red and green LED the I/O direction are already setup (it goes from red to green when you solve the level 2) you just need to set some 1’s into the GPIO’s register to light the 2 LEDS together.

The LEDs are connected to the PortB of the CPU, red = PB12 and green = PB13:

The register to control the output level is 0x40010C10. Set 0x40010C10 to 0x3000 will light the 2 LEDs.

This simple shellcode will do the job:

About the dumpcode, you need to handle the serial port. Means waiting for bytes gets outside without override the previous one, not sent yet. The bit you need to care is the TXE: if it’s 0, it busy, if it’s 1 you can send the next byte.

Then the rest of the shellcode is strait away, get a byte, send it if the interface isn’t busy:

And the CPU sends over the serial port the full firmware. This shellcode was already seen in the Balda’s course, during Insomni’hack training in 2016.

Game over!

Conclusion: A fun challenge by Baldanos, as usual I must said. This one was tricky but solvable during a CTF. We were only 4 team to solve the last stage, not so obvious in fact.


CTF hosted by Insomni’hack

Hardware challenges by @Baldanos

Solved with the help of Azox idle wog and @smillier3

Pièces jointes

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Post Navigation