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.


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 “” 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, “” 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.

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

Flare-On 2021 Write-ups

I am actively job-hunting and available
Interested? Feel free to reach