AlexCTF 2017 : rev100-c++_is_awesome

They say C++ is complex, prove them wrong!

Solution

As always, started by checking binary details/protections..

intrd@inix:~/ctf/alexctf2k17/rev100$ file re2

re2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=08fba98083e7c1f7171fd17c82befdfe1dcbcc82, stripped

intrd@inix:~/ctf/alexctf2k17/rev100$ python -c 'from pwn import *; elf = ELF("./re2")'

[*] '/home/intrd/ctf/alexctf2k17/rev100/re2'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE

..and disabled the ASLR protection to stop messing the memory addresses allocated to our program.

sudo bash -c "echo 0" > /proc/sys/kernel/randomize_va_space  

The program apparently consists of sending the correct flag as parameter.. otherwise it returns the error message..

intrd@pwn4food /media/sf_ctf/alexctf2k17/rev100# ./re2 asd  
Better luck next time  

Launched radare2 w/ a dummy flag AXXX and started by debugging the main function.

Searching by the string Better luck next time found the function fcn.00400b56 which is called if this cmp fails. Set a breakpoing on it.

It compares dl with al, where dl=rdx and al=rax.

Dumping the registers

It is comparing the first letter of my test flag stored in rdx with the rax value, possibly the correct letter of the flag.

In this case rdx=0x41=A and rax=0x41=A, the cmp is true program loop to compare the next letter..

Continuing the program, now rdx=0x58=X and rax=0x4c=L, the compare fails because we are using a dummy flag AX.., but now we are sure that the rax is really storing the correct letter of the flag.

ALEXCTF uses the flag format ALEXCTF{} so we know the first 8 letters, let's grab the next one debugging w/ the payloader ALEXCTF{X

As you can see, the program is expecting the W letter 0x00000057, we can continue doing this manually but is painful!

Bruteforcing the binary

Knowing that the program tests letter by letter of the flag and exits when the letter is wrong we can easily launch a bruteforce.

Used crunch to create a wordlist w/ all possible characters..

intrd@inix:~$ crunch 1 1 "@$,.\!/\'\"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}" -o ~/ctf/alexctf2k17/rev100/1_alphanumsimbs.txt

Crunch will now generate the following amount of data: 148 bytes  
Crunch will now generate the following number of lines: 74  
crunch: 100% completed generating output  

.. and wrote a pipe bruteforcer script to process it