This is an Arduino (AVR) challenge. You can read the full official solution from FireEye, here I just want to show how we can just find use “grep” to quickly find the decryption function to get the flag.

At first, I was going to try to understand what this binary does, but before going too deep, I had an idea: this binary is so small, what if I can just find the flag string without looking at the program’s logic. Looking at the strings present in the binary, it is obvious The flag is not in cleartext, so it must be encrypted somehow.

Most encryption algorithm will involve the use of XOR (`eor`

in AVR). Looking at the disassembly, all EORs are just to clear a register (e.g: `eor r1, r1`

). There is only one `eor`

in `0xaee`

that is not clearing a register (`eor r25, r24`

), which is the last one in this `grep`

output.

<br /> $ avr-objdump -m avr -D remorse.ino.hex |grep eor<br /> c4: 11 24 eor r1, r1<br /> 1ec: 99 27 eor r25, r25<br /> 2e6: 99 27 eor r25, r25<br /> 340: 11 27 eor r17, r17<br /> 59e: 88 27 eor r24, r24<br /> 742: 11 24 eor r1, r1<br /> 78e: 11 24 eor r1, r1<br /> 7f2: 11 24 eor r1, r1<br /> 904: 11 24 eor r1, r1<br /> a16: 11 24 eor r1, r1<br /> aee: 98 27 eor r25, r24<br />

Looking at the code around it: it is a single loop, with `eor`

and `subi`

. This must be the decrypt loop.

<br /> ae6: ldi r26, 0x6C ; 108<br /> ae8: ldi r27, 0x05 ; 5<br /> aea: ldi r18, 0x00 ; 0</p> <p>decrypt:<br /> aec: ld r25, Z+<br /> aee: eor r25, r24<br /> af0: add r25, r18<br /> af2: st X+, r25<br /> af4: subi r18, 0xFF ; 255<br /> af6: cpi r18, 0x17 ; 23<br /> af8: brne .-14 ; 0xaec<br />

We just need to find the encrypted data pointed by Z (which is a pair of R31:R30), and r24 (the xor key). Looking a bit up, we found the code that fills in the encrypted data. It sets Z with the value of Y (pair of R29:R28), clears the memory, and fill it with some bytes.

<br /> a80: movw r30, r28 ; Z = Y<br /> a82: adiw r30, 0x01 ; Z++<br /> a84: movw r26, r30 ; X = Z<br /> a86: ldi r25, 0xFF ;<br /> a88: add r25, r30 ; </p> <p>clear:<br /> a8a: st X+, r1<br /> a8c: cpse r25, r26<br /> a8e: rjmp .-6 ; 0xa8a </p> <p> a90: ldi r25, 0xB5<br /> a92: std Y+1, r25<br /> a94: std Y+2, r25<br /> a96: ldi r25, 0x86<br /> a98: std Y+3, r25<br /> a9a: ldi r25, 0xB4<br /> a9c: std Y+4, r25<br /> a9e: ldi r25, 0xF4<br /> aa0: std Y+5, r25<br /> aa2: ldi r25, 0xB3<br /> aa4: std Y+6, r25<br /> aa6: ldi r25, 0xF1<br /> aa8: std Y+7, r25<br /> aaa: ldi r18, 0xB0<br /> aac: std Y+8, r18<br /> aae: std Y+9, r18<br /> ab0: std Y+10, r25<br /> ab2: ldi r25, 0xED<br /> ab4: std Y+11, r25<br /> ab6: ldi r25, 0x80<br /> ab8: std Y+12, r25<br /> aba: ldi r25, 0xBB<br /> abc: std Y+13, r25<br /> abe: ldi r25, 0x8F<br /> ac0: std Y+14, r25<br /> ac2: ldi r25, 0xBF<br /> ac4: std Y+15, r25<br /> ac6: ldi r25, 0x8D<br /> ac8: std Y+16, r25<br /> aca: ldi r25, 0xC6<br /> acc: std Y+17, r25<br /> ace: ldi r25, 0x85<br /> ad0: std Y+18, r25<br /> ad2: ldi r25, 0x87<br /> ad4: std Y+19, r25<br /> ad6: ldi r25, 0xC0<br /> ad8: std Y+20, r25<br /> ada: ldi r25, 0x94<br /> adc: std Y+21, r25<br /> ade: ldi r25, 0x81<br /> ae0: std Y+22, r25<br /> ae2: ldi r25, 0x8C<br /> ae4: std Y+23, r25<br />

Going a bit up again, we found a `ret`

(return), which means its the end of another function/subroutine. It seems that `r24`

is filled somewhere else by the caller of this decrypt function.

It doesn’t matter, `r24`

is just an 8 bit register (256 possible values). Translating this to python, with a brute force loop:

<br /> a = "b5b586b4f4b3f1b0b0f1ed80bb8fbf8dc68587c094818c".decode("hex")</p> <p>for key in range(0, 256):<br /> s = ''<br /> for i,c in enumerate(a):<br /> m = ((ord(c)^key) + i)&0xff<br /> s = s + chr(m)<br /> print key, hex(key), s</p> <p>

And since all flags always have a flare-on.com suffix, we can just add a grep:

<br /> $ python brute.py|strings|grep flare<br /> 219 0xdb [email protected]<br />

So the flag is `[email protected]`

and the key is 219 decimal (0xdb).