0xd13a

A rookie in a world of pwns

FLARE-ON 2017 Writeup: covfefe.exe

At a first glance this challenge looks simple - the code is just a few pages long. However the closer look reveals the dreaded Subleq esolang. The code is essentially an interpreter for the “machine code” with thousands of subleq instructions :worried:

Interpreter simplicity, however, is our ally here. We can quickly implement it in Python and run the program while printing out our own debug information - basically take full control of the execution. Here I implemented a simple interpreter for the program, and added a bunch of debug output that helped me analyze the logic: interp.py

We can run the program with a bunch of inputs:

1
2
3
4
C:\work\flareon17\covfefe>\Python27\python.exe interp.py test
Welcome to the magic box.
Enter the password: test
Password Failed. You have used insufficient computer science. Have you considered a career in sales instead?

Running it with a -t parameter prints out the full run trace; we can capture a number of them and compare them to analyze what is happening:

1
2
3
4
5
6
7
8
9
10
11
12
13
C:\work\flareon17\covfefe>\Python27\python.exe interp.py -t test
    463: 0(0) 0(0) =(0) 467 jmp 467
    467: 466(0) 466(0) =(0) 0 next 46a
    46a: 476(5) 0(0) =(fffffffb) 0 next 46d
    46d: 0(fffffffb) 466(0) =(5) 0 next 470
    470: 0(fffffffb) 0(fffffffb) =(0) 0 next 473
    473: 0(0) 0(0) =(0) 477 jmp 477
    477: 49b(0) 49b(0) =(0) 0 next 47a
    47a: a1(9d) 0(0) =(ffffff63) 0 next 47d
    47d: 0(ffffff63) 49b(0) =(9d) 0 next 480
    480: 0(ffffff63) 0(ffffff63) =(0) 0 next 483
    483: 49c(0) 49c(0) =(0) 0 next 486
...

As we look over the execution traces a number of interesting facts are discovered:

  • 0x111 is the location of the error message that is printed when the input is incorrect

  • 0xefa is the location of each character to be printed

  • Read input characters are stored in the address range [0x4d,0x6c]

  • The following address ranges are loops that contribute to decoding of individual characters: [0xb50,0xc77], [0xca1,0xdc8], [0xa79,0xab1], and [0xaf6,0xb32]

When we run the program with those locations annotated we can see that when the input string is accepted by the program it is processed two characters at a time. Those characters are put through the 4 loops that we identified followed by a small block of instructions that looks like it is checking correctness of characters that were specified. After that the next 2 characters are retrieved and the process repeats.

In that small block of instructions there is an interesting sequence of steps:

1
2
3
4
5
6
7
...
def: e98(f7de) e99(35e8a) =(266ac) 0 next df2
df2: e99(266ac) 0(0) =(fffd9954) df8 jmp df8
df8: 0(fffd9954) 0(fffd9954) =(0) 0 next dfb
dfb: 0(0) e99(266ac) =(266ac) e04 next dfe
dfe: ead(1) ead(1) =(0) 0 next e01
...

Note that at 0xdef we are subtracting value at location 0xe98 from value at location 0xe99. Value at location 0xe98 changes as we supply different first 2 characters as input. In this run they did not match and what looks like a “success” flag is cleared at location 0xead. This means that we can “bruteforce” the characters to make the values at position 0xdef match, which will leave the “success” flag untouched. (Bruteforcing here does not mean blind checking of all possible character combinations but rather trying of most likely candidates in order to approximate the values)

Within several attempts we find that characters su make the values match:

1
2
3
4
5
6
...
def: e98(35e8a) e99(35e8a) =(0) 0 next df2
df2: e99(0) 0(0) =(0) df8 jmp df8
df8: 0(0) 0(0) =(0) 0 next dfb
dfb: 0(0) e99(0) =(0) e04 jmp e04
...

We record them and move on to next section in the trace and repeat the same process for the next 2 characters. With this approach we can recover the complete input string within an hour or two: subleq_and_reductio_ad_absurdum. Entering it as the input to the original application gives us the flag:

1
2
3
4
5
C:\work\flareon17\covfefe>covfefe.exe
Welcome to the magic box.
Enter the password: subleq_and_reductio_ad_absurdum
The password is correct. Good Job. You win Flare-On 4.
Your key to victory is: subleq_and_reductio_ad_absurdum@flare-on.com