CYSCA '17 - Protoverse RE

May 12 2017

The premise of the challenge is that there is some weird string in the data section and it is compared against user input in a weird way - across two reads from STDIN.

The string was:


The first read (Login:) reads in a string, and the length of this string (including new line character) will be used as the offset of the weird string which will be used to strncmp() the next user input (Password:) against the weird string.

snprintf((char *)&someBlock, 0xFu, "%s", &weirdStr[loginStrLen]); // copy from the weird string into someblock
if ( !strncmp((const char *)&inputStr, (const char *)&someBlock, 0xFu) )// first 15 chars of password have to match somebloc

However the string which is copied as a substring of the weird string (at the inputLen offset) into a buffer, to compare with the user input, is only 14 bytes - when 15 are compared in the strncmp(). And the length of our user input (including newline) is used as an offset into the weird string to compare with our second round of input - so the full 15 bytes of the weird string will be compared with the 14 bytes copied from the weird string at the offset.

So we just null terminate our user input early to ensure the strncmp() passes.

Resulting in:

[email protected] ~/shared/cysca > python
[+] Opening connection to on port 9007: Done
[*] Switching to interactive mode
 Welcome to the House of the Rising Sun
             `o                              o'
               `o                          o'
                 `o                      o'
                   `o,        o'
                     .d''~    ~`b.    '
                    d'           ``b
                   d'              `b
                  d'                `b
 .o.o.o.o.o.o.o. ;0 flag{g00d_t!m3$} `b .o.o.o.o.o.o.o.
[*] Got EOF while reading in interactive

My exploit:

from pwn import *

r = remote('', 9007)

print r.recvuntil('Login:')

# set the length of the substring to use (4 incl. newline)

print r.recvuntil('Password:')

# send the substring and null terminate since the binary actually only reads 14 and not 15 chars...

# read flag