Friday, April 7, 2017

Nuit du Hack XV Quals - Reverse 350: Matriochka step 4 (I did it again)

Binary file download : https://goo.gl/MhVl0g

This script, when executed under IDA, writes the correct input to an output file :

from idc import *
from ctypes import c_uint32
def bruteforce_word(dword1,dword2):
for i in range(0,256) :
for j in range(0,256) :
k = 0
result = c_uint32(0xffffffff)
while k < 2 :
if k == 0 :
result.value ^= c_uint32(i).value
else :
result.value ^= c_uint32(j).value
l = 7
while l >= 0 :
result.value = ( result.value >> 1 ) ^ -(result.value & 1) & dword1
l -= 1
k += 1
result.value = ~result.value
if result.value == dword2 :
return [i,j]
def prepare() :
RunTo(BeginEA())
GetDebuggerEvent(WFNE_SUSP,-1)
#Modify the necesarry registers
RunTo(0x4007F1)
GetDebuggerEvent(WFNE_SUSP,-1)
SetRegValue(0x400000,"RDI")
RunTo(0x40084F)
GetDebuggerEvent(WFNE_SUSP,-1)
SetRegValue(0x40089D,"RAX")
#First stage
RIP_access_list = []
prepare()
ptr_input = DbgQword(GetRegValue("RDX"))
AddBptEx(ptr_input,1,BPT_RDWR)
while GetDebuggerEvent(WFNE_CONT|WFNE_ANY, -1) == BREAKPOINT :
RIP_access_list.append(GetRegValue("RIP"))
DelBpt(ptr_input)
#Second stage
last_access = RIP_access_list[-1]
AddBptEx(last_access,1,BPT_EXEC)
prepare()
GetDebuggerEvent(WFNE_CONT|WFNE_ANY,-1)
DelBpt(last_access)
file = open("flag.txt","wb")
while DbgByte(ptr_input) != 0 :
dword1 = DbgDword(GetRegValue("RBP") - 0x3c)
dword2 = DbgDword(GetRegValue("RIP") + 0x54)
bytes = bruteforce_word(dword1,dword2)
file.write(chr(bytes[0])+chr(bytes[1]))
DelBpt(ptr_input)
ptr_input += 2
AddBptEx(ptr_input,1,BPT_RDWR)
if GetDebuggerEvent(WFNE_CONT|WFNE_ANY,-1) != BREAKPOINT :
break
DelBpt(ptr_input)
file.close()
print "[+] Done !"


The flag is simply the md5sum of this file :