Binathlon 200 - ElfQuest 2

In this challenge we were given a corrupt ELF file. Looking at it under a hex editor we can see that the parts of the header had been replaced by the byte 0xCC. By comparing this to other headers of ELF binaries, we were able to figure out the replaced bytes and get the ELF to run.

There were 3 blocks of replaced bytes.

First block was replaced with 01 01 01 00 00 00 00 00 00 00 00 00

Second block with 34 80 04 08

Third block with 00 80 04 08 00 80 04 08

When we run the ELF we are requested to input a key. Looking at the code in IDA we can see that the key needs to be a 32-bit integer inputted in hex.

mov     dword ptr [esp], offset s ; "Here's no way,\nyou must give the key:"
call    _puts
mov     dword ptr [esp+4], 20h ; n
lea     eax, [esp+3Ch]
mov     [esp], eax      ; s
call    _bzero
mov     dword ptr [esp+8], 1Fh ; nbytes
lea     eax, [esp+3Ch]
mov     [esp+4], eax    ; buf
mov     dword ptr [esp], 0 ; fd
call    _read
mov     dword ptr [esp+8], 10h ; base
mov     dword ptr [esp+4], 0 ; endptr
lea     eax, [esp+3Ch]
mov     [esp], eax      ; nptr
call    _strtoul

Our input is then hashed and checked against 2 DWORDs 0x23D18103 and 0x32F5E109. These hash functions use data stored at address 0x1060 in the binary file. Brute forcing the input yielded the key: 0xE13EEE37

Now it was time to figure out what to do with this key. The data at address 0x1060 was definitely not random data, so we tried different ways to decrypt it using the key. It turns out that by adding the key 0xE13EEE37 to each DWORD of the encrypted data produced a 20 byte ELF header, with unrecognizable data after it. It was at this point that the meaning of the title "ElfQuest 2" became clear. We found a writeup to ElfQuest here. By analysing frequencies on the first 20902 bytes of the decrypted data, we were able to obtain a 256-byte file, with another ELF header.

This resulting file had patterns to it, especially with the null bytes, recognizable addresses such as 8C 80 04 08 and recognizable code such as 0xCD 0x80, opcode for the instruction int 0x80. This caused us to this file and here are the results:

The code reads 0x28 bytes starting at address 0x804808C and multiplies it by constant 0x4B. By multiplying the bytes at that corresponding address in the binary file, we were able to get the flag.