Reverse Engineering
Last updated
Last updated
Signal (50 pts)
Here
License (50pts)
Here
Brave Traveler (191 pts)
Here
Virtual Rev (360 pts)
Here
x8 (360 pts)
Here
Functional (476 pts) 🥇
Mcknight (487 pts) 🥈
It functions.
Given program compiled with ghc, lets try to run it.
It only shows "Checking flag..." and there is no process that receive our input when we run the program. Decompile it using IDA. Searching for "Checking flag..." string we will see another string in near the address of "Checking flag..."
Based on information above the program should produce "Wrong!" output if we input incorrect value. Previously i've been reversed program compiled with ghc too in this writeup. So the next step i did is debugging using GDB. Set breakpoint on instruction that call res_evalLazyIO.
Run the program with argument, in this case i tried to check wether our argument is used or not as the input.
Set hardware read breakpoint on 0x4d3410 then continue the program
From image above we know that our input processed and it passed to function base_GHCziForeign_zdwpeekCString_info which is ghc internal function. Continue the program and we will see again that the next index will be processed also. Continue until the program exited we still dont receive any "Wrong" output. In this step i assume that the length should be correct, so lets just bruteforce it.
We can see that there is Wrong output when i == 28 , so our input length should be 28. Lets strace the program. Try with argument "A"*28 , "T" + "A"*27 , "TF" + A*26.
All of the trial give different length of total instruction executed
"A" * 28 -> 262
"T" + "A"*27 -> 386
"TF" + "A"*26 -> 508
All of the trial also delayed for each index, especially if it is correct value. So for example
A -> delay n seconds
TA -> delay 2*n seconds
TFA -> delay 3*n seconds
If i do bruteforce based on time or instruction it can be solved but would take a long time since basically if we do brute force for index 2 it will take 3*n for each character tested. So my approach is trying to find out which function that trigger the delay. During the competition i did some approach but not limited to tracing the "thread", "input", sleeping_queue, etc. In the end i found that there is function getDelayTarget that will make the program delayed based on its argument, in this challenge it will delayed 3 seconds.
If the value is correct it will execute call getDelayTarget
so we can trace the correct value by counting the executed times on 0x497896. Lets patch instruction so it will always do getDelayTarget(0)
The easiest way is jut by changing xor eax,eax to xor edi, edi. After that just do gdb scripting to get the flag.
Flag : TFCCTF{timing_are_a_bit_off}
Knights wear armour, but does it protect them from dragons? Flag format: TFCCTF{sha256(password)}