[Reverse] TUCTF - Unknown


Unknown
200

Diggin through some old files we discovered this binary. Although despite our inspection we can’t figure out what it does. Or what it wants…

unknown - md5: 9f08f6e8240d4a0e098c4065c5737ca6

Reversing the binary

The binary has the following restrictions, we need to provide the correct flag as argv[1] and the length of the flag must have 56 of length as we can see bellow in the assembly:

After this initial checks we are going to have a loop that checks each byte of the flag provided using a big encryption function fcn.00401e90, we can easily check if the byte is correct or not by checking the value of RAX after the function returns as it is explained in the image below:

Radare2 Script

We don’t really need to reverse the encryption function fcn.00401e90, since we can write a radare2 script that checks the return values(RAX) from this function we can just brute-force the flag byte by byte, we need to update the address where the string is stored at each iteration/tentative, and in failed attempts we need to decrement the counter of the loop so we can recheck the same flag byte, this can be done with a script like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import r2pipe
import string
import sys

def transform_string(s):
return ''.join(['%x'% ord(c) for c in s])

def change_address_value(addr, value):
r2.cmd('s %s' % addr)
r2.cmd('wx %s' % value)
r2.cmd('s rip')


flag_try = 'TUCTF{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}'
flag_list = list(flag_try)

r2=r2pipe.open('./unknown', flags=['-2'])
r2.cmd("ood %s" % flag_try)
r2.cmd("aa")
r2.cmd("db 0x401c39")
r2.cmd("db 0x401C82")
r2.cmd("dc")
flag_address = r2.cmd("dr rax")
r2.cmd("dc")
characters = string.ascii_lowercase+ string.digits + '_!}'
for j in range(0,len(flag_list)):
for i,s in enumerate(characters):
if j > 5:
flag_list[j] = s
change_address_value(flag_address, transform_string(''.join(flag_list)))

num = r2.cmd('dr rax')
if int(num,16) == 0x0:
if j > 5:
flag_list[j] = characters[i-1]
change_address_value(flag_address, transform_string(''.join(flag_list)))
r2.cmd('dc')
break
else:
r2.cmd('dr rax = 0x0')
change_address_value('rbp-0xc', '%02x000000' % (j-1))
r2.cmd('dc')
sys.stdout.write('\r'+''.join(flag_list))
sys.stdout.flush()

Running it:

1
2
$ python unknown.py
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}