Today we will solve a simple crack me by avoiding the hard work of reversing the check function. We will use r2pipe
to bruteforce this function after realizing each input character is checked independently.
Overview
The binary receives its input via the argument argv[1]
, which will likely be the flag. The main
function is quite simple and short which made it easy to reverse. We can see it starts by doing a input size check and fails if strlen(input) != 0x38
(as seen in the picture below).
Secondly and most importantly it checks our input and, if we pass all those checks, the program will print flag.
Solution
I noticed that each byte is checked seperately and so I did not need to actually reverse sub_401e90(character, index)
and I could just bruteforce it char by char since this function returns 1 if the character is correct for that index and 0 otherwise.
Knowing that, I created a radare2 script that will run the program with inputs composed of a
*0x38, b
*0x38, etc.. for all printable characters. For each character of each run it will check whether the function returned a 1 or a 0 recovering the flag. Below is the radare script I used to recover the flag and the output of running it.
NOTE: I changed r2pipe to receive args since I didn’t know any other way to pass the args to radare (except for changing the values directly in memory which I didn’t feel like doing).
Exploit
import sys
import r2pipe
import string
import time
FILENAME = "./unknown"
# TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}
flag = list("?"*0x38)
for c in string.printable:
if c == '-': # skip the '-' character (it will work weirdly when passing it to r2's arguments)
continue
# I changed r2pipe to receive args. I don't know how you would pass arguments otherwise inside radare, but if you <char>? enougth you might find a way
r2 = r2pipe.open(FILENAME, flags = ['-d2'], args = [c*0x38])
r2.cmd('aaa')
r2.cmd('db 0x401c82') # After the test function addr
r2.cmd('db 0x401ca1') # END addr
while True:
res = r2.cmd("dc")
rip = int(r2.cmd('dr rip'), 16)
if rip == 0x401ca1:
# print "======================="
# print "======= THE END ======="
# print "======================="
print "".join(flag)
break
elif rip == 0x401c82:
eax = int(r2.cmd('dr eax'), 16)
edx = int(r2.cmd('pf x @ rbp-0xc').split('=')[1], 16)
# print edx, eax
# time.sleep(1)
if eax == 0:
flag[edx] = c
else:
print "We failed:", res
break
r2.quit()
Output
??????????0????0??????????????????0???0?????????????????
??????????0????0??????????????????0???0??????1?1???1????
??????????0????0??????????????????0???0??????1?1???1????
???????3??0?3??0??????????????????0???0??????1?1???1????
???????3??0?3??0???????4?????4????0???0???4??1?1?4?1????
???????3??0?3??0???????4?????4????0???0???4??1?1?4?1????
???????3??0?3??0???????4?????4????0???0???4??1?1?4?1?6??
???????3??0?3?70?7??7??4???7?4????0???0???4?71?1?471?6??
???????3??0?3?70?7??7??4???7?4????0???0???4?71?1?471?6??
???????3??0?3?70?7??7??4???7?4????0???0???4?71?1?471?6??
???????3??0?3?70?7??7??4???7?4????0???0???4?71?1?471?6??
???????3??0?3?70?7??7??4???7?4????0???0???4?71?1?471?6??
???????3?c0?3?70?7?c7??4???7?4????0???0???4?71c1?471?6??
???????3?c0?3?70?7?c7??4?d?7?4????0???0???4?71c1?471?6??
???????3?c0?3?70?7?c7??4?d?7?4????0???0???4?71c1?471?6??
???????3?c0?3?70?7?c7f?4?d?7?4????0??f0???4?71c1?471?6??
???????3?c0?3?70?7?c7f?4?d?7?4????0??f0???4?71c1?471?6??
???????3?c0?3?70?7?c7f?4?d?7h4????0??f0???4?71c1?471?6??
???????3?c0?3?70?7?c7f?4?d?7h4????0??f0???4?71c1?471?6??
???????3?c0?3?70?7?c7f?4?d?7h4????0??f0???4?71c1?471?6??
???????3?c0?3?70?7?c7f?4?d?7h4?k??0??f0???4?71c1?471?6??
???????3lc0?3?70?7?c7f?4?d?7h4?k??0??f0???4?71c1?471?6??
???????3lc0m3?70?7?c7f?4?d?7h4?k??0??f0???4?71c1?471?6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0???4?71c1?471n6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0???4?71c1?471n6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0??p4?71c1p471n6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0??p4?71c1p471n6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0r?p4r71c1p471n6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0r?p4r71c1p471n6??
???????3lc0m3?70?7?c7f?4nd?7h4nk??0??f0r?p4r71c1p471n6??
???????3lc0m3?70?7uc7f?4nd?7h4nk??0u?f0r?p4r71c1p471n6??
???????3lc0m3?70?7uc7f?4nd?7h4nk??0u?f0r?p4r71c1p471n6??
??????w3lc0m3?70?7uc7f?4nd?7h4nk??0u?f0r?p4r71c1p471n6??
??????w3lc0m3?70?7uc7f?4nd?7h4nk??0u?f0r?p4r71c1p471n6??
??????w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??????w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??????w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??????w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C???w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C???w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C???w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
??C?F?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
T?CTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6??
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3?70?7uc7f?4nd?7h4nk?y0u?f0r?p4r71c1p471n6!?
TUCTF?w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!?
TUCTF?w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!?
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!?
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!?
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}