Challenge
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
Summary
It is a typical reverse engineering task where we have to get the password (that in this case is the flag). For this purpose I have used the tools, objdump and radare2, and Python to develop the solution.Solution
$ file unknown
unknown: 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]=53ec94bd1406ec6b9a28f5308a92e4d906444edb, stripped
Looking strings to find where the flag is printed and reverse it.
[0x00401d68]> iz
vaddr=0x00401d64 paddr=0x00001d64 ordinal=000 sz=18 len=17 section=.rodata type=ascii string=0123456789abcdef=
vaddr=0x00401d76 paddr=0x00001d76 ordinal=001 sz=11 len=10 section=.rodata type=ascii string=Try again.
vaddr=0x00401d81 paddr=0x00001d81 ordinal=002 sz=12 len=11 section=.rodata type=ascii string=Still nope.
vaddr=0x00401d8d paddr=0x00001d8d ordinal=003 sz=6 len=5 section=.rodata type=ascii string=Nope.
vaddr=0x00401d93 paddr=0x00001d93 ordinal=004 sz=25 len=24 section=.rodata type=ascii string=Congraz the flag is: %s
[0x00401d68]> axt @ 0x00401d93
data 0x401cbe mov edi, str.Congraz_the_flag_is:__s_n in main
We found the function that executes the encoding and compare with the encoded password (flag). In order to resolve the challenge, we have to reverse this function:
I debugged a bit the first function with GDB and I saw fastly that it returned a md4sum. So, this function will get the md4 hash the n-character of the string and split this string to use just the last 8 characters. After, it converts these characters to numbers and does the following operations:
0x00401f09 mul rbx
0x00401f0c and eax, 0xffffffff
0x00401f0f rol eax, 0x15
The result will be compared with the encoded flag:
0x00401f12 movabs rcx, 0x401dac
0x00401f1c mov rcx, qword [rcx + rsi*4]
0x00401f20 cmp eax, ecx
0x00401f22 je 0x401f2e
So, to generate our script, we just need the encoded flag and it can be found in the address *0x401dac*
$ objdump -j .DATA -s unknown
unknown: formato del fichero elf64-x86-64
Contenido de la sección .DATA:
401dac 7ab5fafd a7492403 2138385f 7ab5fafd z....I$.!88_z...
401dbc 025e4325 0debe259 d756d75e 23f0ff5c .^C%...Y.V.^#.. 401dcc f3bd3992 9b7f2cf6 5f3fe163 848e33d6 ..9...,._?.c..3.
401ddc 23f0ff5c efbd20ff 8e921fc5 5f3fe163 #..\.. ....._?.c
401dec efbd20ff 8e921fc5 71109db5 9b7f2cf6 .. .....q.....,.
401dfc 8e921fc5 70988d38 efbd20ff bac5ecce ....p..8.. .....
401e0c 6b1352a9 41087196 efbd20ff 8e921fc5 k.R.A.q... .....
401e1c fddf36f5 bac5ecce 6b1352a9 c4dad7c5 ..6.....k.R.....
401e2c efbd20ff 612aa912 5f3fe163 71109db5 .. .a*.._?.cq...
401e3c efbd20ff 70988d38 5f3fe163 4e3578cd .. .p..8_?.cN5x.
401e4c efbd20ff 194418f2 bac5ecce 4e3578cd .. ..D......N5x.
401e5c 8e921fc5 dcbfa83c 9b7f2cf6 dcbfa83c .......<..,....<
401e6c 194418f2 bac5ecce 8e921fc5 dcbfa83c .D.............<
401e7c 6b1352a9 4451f32f a75e16ba cd841bef k.R.DQ./.^......
401e8c 38000000 8...
As Intel x86-64 is little endian, in our script we have to write the bytes in reverse.
Here's the python script that get the flag.
#!/usr/bin/env python
from Crypto.Hash import MD4
import string
rol = lambda val, r_bits, max_bits=32: (val << r_bits%max_bits) & (2**max_bits-1) | ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
table = ['fdfab57a','32449a7'
,'5f383821', 'fdfab57a'
,'25435e02','59e2eb0d'
,'5ed756d7','5cfff023'
,'9239bdf3','f62c7f9b'
,'63e13f5f','d6338e84'
,'5cfff023','ff20bdef'
,'c51f928e','63e13f5f'
,'ff20bdef','c51f928e'
,'b59d1071','f62c7f9b'
,'c51f928e','388d9870'
,'ff20bdef','ceecc5ba'
,'a952136b','96710841'
,'ff20bdef','c51f928e'
,'f536dffd','ceecc5ba'
,'a952136b','c5d7dac4'
,'ff20bdef','12a92a61'
,'63e13f5f','b59d1071'
,'ff20bdef','388d9870'
,'63e13f5f','cd78354e'
,'ff20bdef','f2184419'
,'ceecc5ba','cd78354e'
,'c51f928e','3ca8bfdc'
,'f62c7f9b','3ca8bfdc'
,'f2184419','ceecc5ba'
,'c51f928e','3ca8bfdc'
,'a952136b','2ff35144'
,'ba165ea7','ef1b84cd'
,'e6894955']
flag = []
for z in table:
for i in string.printable:
h = MD4.new()
h.update(i)
cad = h.hexdigest()[24:]
number = int(cad, 16)
cal = (number * 0x7a69) & 0xffffffff
n = hex(rol(cal,0x15))[2:]
if (z == n):
flag.append(i)
print "".join(flag)
and the result:
$ python unknown.py
TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}