Solving the Shabak’s Airplane challenge – Task 3

Some time ago I solved the Airplane challenge published by Israeli Shin-Bet (Shabak). The crackme has three levels of increasing difficulty. Each one is a 32 bit Windows application. It was a very pleasant task, not difficult but also not too trivial. In this writeup I will present my solutions.

Task 1 and 2 have been described in the previous part, you can read it here. Now it’s time for the final one!

Task 3

http://10100110110100001100001011000100110000101101011.com/Airplane/3_with_the_best.php

Mirror [task3], password “Challenge”

This time the crackme comes with a hint:

hint:
Maybe this program doesn't do more than it seems, our special agent 
have told us that when the program was executed in a different 
country, it behaved differently

It reminds me of the techniques used by some malware to target only the chosen countries. Usually it is implemented in one of the two ways:

  1. sending a request to some of the services that gives geolocation data basing on the external IP
  2. checking the installed language/keyboard layout

Let’s run the crackme and observe how it behaves, if it makes any internet connections etc. (we can use i.e. ProcMon).

The crackme printed a message: “May you enter Deep and Dreamless Slumber”:

…and terminated after some timeout. No internet connection has been made. So, I guess it will do something about checking the installed language.

This time I will start from the static analysis in IDA. Let’s load the application and have a look at the referenced functions:

There is GetLocaleInfoEx. I suspect it will be involved in verification process, so, let’s follow where it is called:

The output is saved in a variable of WORD size. If I try to follow this variable and check the references, I don’t find anything more than the above line:

However, it’s upper byte seems to be referenced somewhere else!

It seems if this flag matches, some other function is copied on the place of the function printing the initial “slumber” message:

check_cond.png

So, we have some self-modifying code here 🙂 ! Let’s see what is this function doing:

search_dll.png

fs:30h -> PEB
PEB + 0XC -> _PEB_LDR_DATA Ldr
Ldr + 0x14 -> _LIST_ENTRY InMemoryOrderModuleList

It doesn’t seem to be a function printing the password. Instead, it searches Kernel32.dll through the loaded DLLs:

check_next_char.png

We can also see an atypical NOP instruction, that can confuse some debuggers:

confusing_nop

OllyDbg and it’s derivatives fails to parse it properly:

confsing_nop_olly

If we want to analyze it under OllyDbg we need to substitute this fragment by a typical NOP (0x90) in order to get a clear view:

to_nop

Now I will do some dynamic analysis in OllyDbg. I set the breakpoint on the flag check (the one that was deciding whether or not to overwrite the function):

cond_check_olly

…and when it was hit, I changed of the Z flag in the registry. After the function was overwritten, I enforce OllyDbg to re-analyze the code and then set the breakpoint at the function’s beginning:

overwritten_func

When the breakpoint is hit, we can step follow the function’s execution to see is details what it is doing.

At the end there is something interesting – a new PE file in the memory:

unpacked_dll

We can see that the previously stored pointer to kernel32.dll is being overwritten by the pointer to this module:

overwrite_kernel32_ptr

I dumped this PE and unpapped it using pe_unmapper in order to get a better view. It is named stub.dll and it exports one function: GetComputerNameW:

stub_dll.png

After following references in IDA, we can find, that this module was unpacked just before the flag check:

unpacking_stub.png

It was manually loaded in the memory (without being dropped on the disk and without using LoadLibrary function). This trick is also very often used in malware.

Anyways, now we need to find out where the stub.dll is used. So, I set the breakpoint on this module:

bp_at_stub

The breakpoint is hit inside ntdll:

bp_in_ntdll.png

Now I set the breakpoint on the .text section of the main module (Third.exe) to see the point where the execution returns:

bp_2

This is where the stub.dll was referenced from inside the main module:

get_computer_name.png

So, at this point the application gets the address of the function: “GetComputerNameW”. It can fetch this function either from kernel32.dll (if the locale flag was not set) or from the stub.dll (if the locale flag was set).

It seems we are pretty close to the solution, because some formatted printing (“%s”) is done just after that lines (probably this is the flag being printed). Most probably the key  lies inside the function GetComputerName, so let’s go there.

go_to_func.png

Inside GetComputerNameW:

inside_get_comp_name

Again OllyDbg cannot manage parsing some instructions. So, I opened the dumped version of Stub.dll in IDA and used as a reference.

This is how the beginning of the function looks:

get_comp_name.png

fs:30h -> PEB
PEB + 0x10 -> _RTL_USER_PROCESS_PARAMETERS ProcessParameters
ProcessParameters + 0x44 -> _UNICODE_STRING CommandLine.Buffer

The function fetches the command line of the main process, and then process the buffer.

Again, the atypical NOP instructions has been used (marked red on the picture):

weird_nops.png

We can see two buffers being compared. One of them is the command line buffer stored the memory, and another is hardcoded in the stub.dll. Four consecutive DWORDs are compared. If those two buffers are not matching, then the function sets an error code and exits:

buf_check.png

The hardcoded buffer starts at RVA 0x2000 – that is the beginning of .rdata section).

rdata_start

Of course we need the above function to exit without error – then our flag will be printed.

It is easy to conclude, that in order to get the flag, we must have the same values in the memory buffer as in the hardocoded buffer.

I set the breakpoint before this comparison started. The, I just copied the hardcoded buffer and overwritten by its content the buffer in the memory:

overwritten_buf

Now, let it run. And this is what we get:

t3_done

Solved!

We reached the “Airplane Complete” page.

http://10100110110100001100001011000100110000101101011.com/Airplane/Airplane_Complete_U_D_1.html

R. Sanchez is safe, happy end! 🙂

Advertisements

About hasherezade

Programmer and researcher, interested in InfoSec.
This entry was posted in CrackMe and tagged . Bookmark the permalink.

One Response to Solving the Shabak’s Airplane challenge – Task 3

  1. Pingback: Week 26 – 2017 – This Week In 4n6

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s