Time's Up, Again!
Problem
Previously you solved things fast. Now you've got to go faster. Much faster. Can you solve this one before time runs out? times-up-again, located in the directory at /problems/time-s-up--again-_1_014490a2cb518921928db099702cbfd9.
Solution
Decompile the binary file using Ghidra (cheat sheet).
main()
function:We cannot use the same script as in the previous challenge,
Time's Up
, because we only have 200 uSeconds.pwntools
is too slow.We will use
SIGSTOP
andSIGCONT
to pause to resume the program before the timer can expire. Wikipedia description ofSIGSTOP
andSIGCONT
: "When SIGSTOP is sent to a process, the usual behaviour is to pause that process in its current state. The process will only resume execution if it is sent the SIGCONT signal. SIGSTOP and SIGCONT are used for job control in the Unix shell, among other purposes. SIGSTOP cannot be caught or ignored."The script.py works by:
Running times-up-again
Waiting for...
the moment right before the alarm is about to go off (which would trigger the
SIGALRM
signal and end the program)the moment after the problem has been printed
Pausing the program with the
SIGSTOP
signalSolving the mathematical equation given by the program using
eval()
Sending the answer and a newline
Flushing the
stdin
and resuming the program by sending theSIGCONT
signalWaiting 0.2 seconds for the program to output success or failure.
Checking 4 lines of output for the word "pico". If it is found, the line is printed and the program ends. If "pico" does not appear, restart from step 1.
I tweaked the sleep amount and settled on
0.000175
seconds since it works well most of the time.I attempted to use the threading.Timer class, as discussed in this StackOverflow answer, in order to handle the rare cases that make the script.py appear to hang. However, using it caused delays and messed with the exact timing needed to run this script.
The original program was likely written in a language that does not implicitly support arbitrary-percision integers (
python
does). Also, the binary is only 64-bit:times-up-again: ELF 64-bit LSB shared object
(output fromfile times-up-again
). Thus, any integer we want to pass into the program we should turn back into 64-bit. This can be done with%pow(2,64)
or%(1 << 64)
. Other write-ups usedctypes.c_longlong
instead of these techniques, but I could not get this to work.SIGSTOP
cannot be caught, which means the process doesn't even know it ever received the signal.Run the script.py. If it hangs for more than a second, kill it with
^C
and rerun. It will work eventually. Example output below (only two tries!):Other Write-ups: C program by Dvd848 (Archive) and Python script that runs fast enough by AMACB (Archive)
Flag
picoCTF{Hasten. Hurry. Ferrociously Speedy. #3b0e50c7}
Last updated