B1g_Mac
Problem
Here's a zip file. You can also find the file in /problems/b1g-mac_0_ac4b0dbedcd3b0f0097a5f056e04f97a.
Solution
Unzip
b1g_mac.zip
withunzip b1g_mac.zip
to get a folder calledtest
(with 18 images inside) and amain.exe
executable file.Running the
main.exe
file producesNo flag found, please make sure this is run on the server
, which is an interesting error message because this file cannot be run on the shell server since it is a Windows executable and the shell server runs Linux.Creating a fake flag file with
echo picoCTF{fake_flag} > flag.txt
and rerunning the program results in the following:Since something happened lets see if the files are any different by re-extracting the test directory from the zip file and comparing it to the contents of the current test directory:
diff -r test/ test_original/
. Nothing appears to have changed. Lets reset thetest
directory and delete the "new" folder in case it actually changed something.Reverse the binary file using Ghidra (cheat sheet). Open it and in the symbol tree click on main. The decompiled main function will show on the left.
The program opens the flag file, reads 18 characters, initializes some globals and then calls
_listdir
(after printing"Work is done!"
which is strange because nothing much is done before that message is printed)._listdir
function:_listdir
is a recursive function which iterates over files in the folder (it was called with the folder"./test"
by the main function) and, ifparam_1
if 0, it calls _hideInFile for every other file (only the'Copy'
files). Ifparam_1
is set to 1,_decodeBytes
is called on the file instead.Right click
_listdir
and go to "References > Find references to _listdir". One of the three options is an uncalled function labeled_decode
:The
_decode
function uses the same_folderName
global variable as the main function. We can call_decode_
using the debugger after_folderName
gets initialized in the main function.Get location in main right after initializing
_folderName
:0x00401bda
Get address of
_decode
:0x00401afe
Debugger and Get Flag 1. Linux (
winedbg
- did not work): Open in GDB withwinedbg main.exe
then set a breakpoint at0x00401bda
withbreak *0x00401bda
(the*
means "address" instead of function) thennext
thenset $eip = 0x00401afe
thennext
and get the flag. 2. Windows (x32dbg
- Successful): It is important that the file times in the zip are not changed. On Windows, use7-zip
to open and extract these files without modifying their file times. The built-in to Windows extraction option does not work. Runx96dbg
from x64dbg and selectx32dbg
. Then openmain.exe
inx32dbg
and runSetBPX 00401bda
to set a breakpoint at0x00401bda
. Next, click through "run" until this breakpoint is reached. When the breakpoint is hit, runEIP=00401afe
to change theEIP
to_decode
. "Run" one more time and get the flag._hideInFile
function:We can see that the function is using
GetFileTime
andSetFileTime
, and this also explains the challenge name (MAC stands for "Modification, Access, Creation"). The Windows user interface shows us the date and H:M:S, but NTFS file systems have a resolution of 100 Nanoseconds for these fields (TheFILETIME
structure represents the time in 100-nanosecond intervals since January 1, 1601). More info about how the flag was encoded and how to write a script to decode it: Dvd848 (Archive) and AMACB (Archive)
Flag
picoCTF{M4cTim35!}
Last updated