Rating: 5.0


"""
Title: 8byte
Points: 432

Summary:
My friend has sent me this packed binary. Can you understand what it does and extract the flag?

Explanation:
The binary executes an hidden function that is ciphered in section .awsm.
Each instruction of the function is ciphered and separated by 0x1337 values. Basically the function @0x4020c0 iterates over the bytes of .awsm until finding the value 0x1337. Each bytes are deciphered using the function @0x401520 and copied into a 8 bytes buffer. Then this buffer is copied @ 0x407001. The function then jumps @0x407000 and execute the instruction and the function @0x4020c0 is executed again until 0xdeadbeef is found in .awsm.
This hidden function first check that length of input is 0x20, then checks each bit of each byte of the submited flag.

Solution:
I first extract .awsm section, and deciphered the data. After disassembling these instructions, I just spot the insctruction that targeting the right byte (imul or shl instructions). Then I find which bit is tested (with and instruction) and if this bit have to be setted or not(jne/je jumps).

"""
from capstone import *

def FUN_00401760(x):
a = x ^ 0x35
a -= 12
return a & 0xff

def FUN_00401840(x):
a = x ^ 0xaa
a += 0x15
return a & 0xff

def FUN_004017e0(x):
a = x ^ 0x75
a += 12
return a & 0xff

def FUN_004017a0(x):
a = x - 0x21
return (a & 0xff) ^ 0xca

def decrypt(x):
cVar1 = FUN_00401760(x)
iVar2 = FUN_00401840(cVar1 - 0xd)
iVar2 = FUN_004017e0(iVar2 + 3)
cVar1 = FUN_00401760(iVar2 - 0x15)
iVar2 = FUN_00401840(cVar1 + 0xf)
uVar3 = FUN_004017a0(iVar2 - 0x14)
uVar3 = FUN_004017a0(uVar3 + 0xd)
return FUN_00401760(uVar3 - 0xc)

# get the binary
f = open("binary.exe","rb")
PE = f.read()
f.close()

# find the ciphered hidden function
pat1 = bytes.fromhex("cc371392 a337132a a3433713 760cab68".replace(" ",""))
pat2 = bytes.fromhex("cccccccc cccccccc cccccccc cccccccc".replace(" ",""))
start = PE.index(pat1)
end = PE.index(pat2) + len(pat2)
awsm = PE[start:end]

# decipher hidden function
instr = []
code = b""
while len(awsm):
if awsm[:2] == b"\x37\x13": # 0x1337
awsm = awsm[2:]
if code:
instr.append(code)
code = b""
elif awsm[:4] == b"\xef\xbe\xad\xde": # 0xdeadbeef
break
else:
x = awsm
awsm = awsm[1:]
c = decrypt(x)
code += bytes([c])

# dissas hidden function
asm = []
md = Cs(CS_ARCH_X86, CS_MODE_32)
for x in instr:
for i in md.disasm(x, 0x407001):
asm.append("%s\t%s" % (i.mnemonic, i.op_str))

# get flag
D = asm[20:]
flag = [0 for x in range(0x20)]
i = 0
j = 0
for k,d in enumerate(D):
if "imul" in d:
x = d.split(",")[-1].replace(" ","")
if "0x" in x:
x = int(x.replace("0x",""),16)
else:
x = int(x)
i = x
elif "shl" in d:
x = int(d.replace(" ","").split(",")[-1])
i = 1 << x
elif "and" in d:
x = d.split("#").replace(" ","").split(",")[-1]
if "0x" in x:
x = int(x.replace("0x",""),16)
else:
x = int(x)
j = x
if "jne" in D[k+1]:
flag[i] |= j

FLAG = "".join( [chr(x) for x in flag] )
print(FLAG)

# KAF{e1ght_byt3s_1s_4ll_1t_t4k3s}