CSAW Reverse 100 — Rock

stargravy
stargravy
Published in
3 min readSep 19, 2016

When you first run rock you just get a blank prompt. Input a couple of characters and you get a couple of quotes from the talented Dwayne “The Rock” Johnson, and a message saying “Too short or too long” unless you guessed (or checked) the right length.

‘derp’ wasn’t the flag :(

Checking the code shows that the input length is supposed to be 30 characters long (notice the comparison against 0x1e, 30 in hex).

If you input 30 * ‘A’ you get a message telling you that you did not pass 0. Checking the code shows that each of the thirty characters is checked against some value, and rock will tell you if that character has passed or not.

Looking around the code you can find a string “FLAG23456912365453475897834567” which appears to be what our characters are checked against. However if you input this you still don’t pass.

This is the test resulting in a pass or fail of our characters

We can place a breakpoint at 0x40183c from the code seen above, just as rock is about to compare our characters, and check the RCX register to see what is being checked against the FLAG string. Turns out our input has been transformed, as can be seen below.

C)>D doesn’t spell FLAG

So, we have two options now: We can do this manually, or just bruteforce it. I did it both ways, because why not. To test it manually I input all printable ASCII characters, 30 at a time, as input, checked the transformed string in gdb, and made a key of the corresponding characters:

F L A G 0 1 2 3 4 5 6 7 8 9
I o D J s t u v w x y z { \

Which, replacing the 30 character string, gives you the flag: Flag{IoDJuvwxy\tuvyxwxvwzx{\z{vwxyz}

That, or you can python it away like in the video (and code snippet) below.

Looks kinda cool :)
#!/usr/bin/python

from subprocess import Popen , PIPE
import string

charset = string.printable
ans = []
for l in range(0,30):
ans.append('A')

num = 0

while num < 30:
for j in charset:

proc = Popen('/root/csaw/rock', bufsize=1 ,stdin=PIPE, stdout=PIPE )
text = ''
ans[num] = j
print ''.join(ans)
proc.stdin.write("".join(ans)+'\n')
for line in iter(proc.stdout.readline,b''):
if ("Pass %d"%num in line):
text = line
if num == 29 and 'Flag' in line:
print line

if("Pass %d"%num in text and "did not pass %d"%num not in text):
num +=1
proc.stdin.close()
proc.stdout.close()
break
proc.stdin.close()
proc.stdout.close()

Happy Hacking!

--

--