[dreamhack] captain-hook writeup
https://dreamhack.io/wargame/challenges/51
import frida import sys def on_message(message, data): print(message) # JavaScript code to be injected jscode = """ var file = new File("dump.txt", "a") //hook GdipSetSmoothingMode, add counter and print out counter each when it get called var counter = 0; const base = Module.findBaseAddress('CaptainHook.exe') Interceptor.attach(Module.findExportByName(null, "GdipSetSmoothingMode"), { onEnter: function(args) { counter++; //console.log("GdipSetSmoothingMode called: " + counter); } }); Interceptor.attach(Module.findExportByName(null, "GdipCreatePen1"), { onEnter: function(args) { // Check if the first argument is 0xFF000000 if (!this.context.rbx.equals(0xFF000000)) { // console.log("rbx != 0xFF000000, skipping..."); // Modify the return address to skip the function execution args[0] = ptr(0); args[1] = ptr(0); args[2] = ptr(0); args[3] = ptr(0); } else { //console.log("GdipCreatePen1 called: " + (this.returnAddress.sub(base).toString(16))); var ret_addr = this.returnAddress.sub(base); var str = ""; /*0 -> a252 맞음 1 -> b5c3 맞음 2 -> ca7e 맞음 3 -> df2c 맞음 4 -> f36e 맞음 5 -> 1081f 맞음 6 -> 11d4d 맞음 7 -> 1318b 맞음 8 -> 14723 맞음 9 -> 15c38 맞음 a -> 26dd 맞음 b -> 3b95 c -> 4fe0 맞음 d -> 6424 맞음 e -> 78e6 맞음 f -> 8d38 맞음*/ if (ret_addr == 0xa252) str = "0"; else if (ret_addr == 0xb5c3) str = "1"; else if (ret_addr == 0xca7e) str = "2"; else if (ret_addr == 0xdf2c) str = "3"; else if (ret_addr == 0xf36e) str = "4"; else if (ret_addr == 0x1081f) str = "5"; else if (ret_addr == 0x11d4d) str = "6"; else if (ret_addr == 0x1318b) str = "7"; else if (ret_addr == 0x14723) str = "8"; else if (ret_addr == 0x15c38) str = "9"; else if (ret_addr == 0x26dd) str = "a"; else if (ret_addr == 0x3b95) str = "b"; else if (ret_addr == 0x4fe0) str = "c"; else if (ret_addr == 0x6424) str = "d"; else if (ret_addr == 0x78e6) str = "e"; else if (ret_addr == 0x8d38) str = "f"; else str = "unknown"; if (str != "unknown") { file.write(str); console.log(str); } } } }); """ def main(target_process): # Attach to the process session = frida.attach(target_process) # Create a script with the provided JavaScript code script = session.create_script(jscode) script.on('message', on_message) # Load the script into the process script.load() # Keep the Python script running until interrupted print("Press Ctrl+C to stop.") try: sys.stdin.read() except KeyboardInterrupt: pass # Detach the session session.detach() if __name__ == "__main__": main("CaptainHook.exe")
Extract another PE file which contains flag via above code.
After that, patch following code to nop(s) to get the flag:
extracted.exe+16FD – FF 15 451B0000 – call qword ptr [extracted.exe+3248] { ->gdiplus.GdipCreatePen1 }