Intro
When we run the exe, we see that all the buttons are disabled. There is no button to click. So we close the dialog and start our analysis.
Write-Up
When we first disassemble the spel.exe
, we see a huge function in the beginning of the file. We can put a breakpoint at the end of this function and so we can save that file and check the contents. When we check the file, we see that it is a DLL file. It doesn’t end in here. If we check this DLL file, we see that it has another DLL embedded. We can easily dump this DLL and can easily disassemble this file. It has only one exported function called Start
DLL doesn’t use a standard import table, instead, it uses hash-based imports. It gets the address of the function by checking the export table of the DLL and calculate the hash of this function. If the hash matches, it returns the address of the function.
This challenge has a lot of booby traps, if you don’t see them, it “takes a break” by calling “Sleep” or “SleepEx” functions.
First Trap
It gets the name of the file and compares it to Spell.EXE. So change the name of the file to Spell.EXE
Second Trap
There is a SleepEx
call just after the name comparison. Patch that call.
Third Trap
It tries to connect “inactive.flare-on.com” We can easily pass that by creating a fake server and change the hosts
file to point to our server. Exe first sends ’@’ to the server. If you send “exe” back, it sends ”#” and runs the code that is coming back. We can’t guess that so it is a trap.
If you send “run” back when it asks ’@’ then it sends ”&” and again runs the code that is coming from the server. It is another trap.
However, if you send, “flare-on.com” it continues.
Fourth Trap
It then tries to decrypt the resource with AES and set two keys under HKCU\Software\Microsoft
. This is where I got stuck. Because I didn’t see what was happening.
There was a huge switch statement. In each case, it was XORing the result of the AES operation with two big keys.
loc_1800027B3:
cmp edx, 16h
ja def_1800027D0
movsxd rax, edx
mov ecx, ds:(jpt_1800027D0 - 180000000h)[rcx+rax*4]
lea rax, cs:180000000h
add rcx, rax
jmp rcx
It seems, xor keys at xmmword_180015180
and xmmword_180015160
was hiding the flag. You either note each byte in every switch statement or, you could zero out xmm0 and xmm1 registers after the below line. So it will show the correct flag.
movdqa xmm0, cs:xmmword_180015180
mov rbx, rcx
movdqa xmm1, cs:xmmword_180015160
b3s7_sp3llcheck3r_ev3r@flare-on.com
Flare-On 2021 Write-ups