Reverse Engineering

After my last post about CTB-Locker I received a lot of e-mails from people asking for a complete analysis of the malware. Most of them wanted to know if it’s possible to restore the compromised files without paying the ransom. The answer is simple: it’s impossible without knowing the Master key! That key resides on the malicious server and it’s the only way to restore every single compromised file.

There are a some articles on the net about CTB-Locker’s modus-operandi. Everyone knows that ZLib is used, AES is used but only few of them mention the use of SHA256+Curve. To explain everything in details I’ll show you how encryption/decryption is done, step by step.

Preamble: HIDDENINFO
HiddenInfo file is the core of the malware, it’s full of precious data. There’s no need to explain every field of the file, a closer look at the first part of it would suffice because it has an important part in the encryption/decryption scheme.

Curve25519 is used to generate the corresponding public key. You can recognize the algo from Basepoint vector because it’s a 0x09 byte followed by a series of 0x00 bytes (For a quick overview over the Elliptic curve algorithm used by the malware take a look here: http://cr.yp.to/ecdh.html).
GenSecretAndPublicKeys is called two times, so two private and two public keys are created. I name them as ASecret, APublic, BSecret and BPublic.

SHA256(curve_25519(Shared_1, BSecret, MPublic))
Shared secret computation takes place. MPublic is the Master public key and it’s visible inside the memory address space of the malware. The Master secret key remains on the malicious server. To locate the Master public key is pretty easy because it’s between the information section (sequence of info in various languages) and the “.onion” address. Shared secret is then putted inside SHA256 hash algorithm, and the result is used as a key for AES encryption:

So, two public keys are visible, but private key ASecret is encrypted. It’s impossible to get the real ASecret value without the AES key…
Ok, now that you know how HiddenInfo file is created I can start with the file encryption scheme.

InfoVector is a sequence of 16 bytes with the first four equals to “CTB1″, this tag word is used to check the correctness of the key provided by the server during the decryption routine.
The decryption demonstration feature, implemented by the malware to prove that it can restore the file, uses
AES_KEY_2 directly. If you remember the key was saved inside HiddenInfo, there are a total of five saved keys.
In this case if you have CSecret you can easily follow the process described above (remember that APublic comes from the first 32 bytes of HiddenInfo), but without CSecret it’s impossible to restore the original files.

It’s important to note that in the encryption process CTB-Locker doesn’t need an open internet connection. It doesn’t send keys/data to the server, it simply encrypts everything! Internet connection is needed in the decryption part only.

CTB-Locker file decryption
At some point, before the real decryption process, there’s a data exchange between the infected machine and the malicious server. The malware sends a block of bytes (taken from HiddenInfo) to the server and the server replies sending back the unique decryption key. The block is composed by the BPublic key, SecretInfo and some minor things:

The malware uses the key to restore the files. Do you remember the decryption part from my last post? Well, the real decryption scheme is not so different. There’s one more step, the calculation of the AES key. To do that the unique key sent by the server is used to decrypt every file:

The server receives DataToServer and it applies the principle of elliptic curve:

Curve_25519(Shared_1, MSecret, BPublic)

Shared_1 from the server is equal to Shared_1 calculated in the HiddenInfo creation part.
Now, with Shared_1 it AES decrypts SecretInfo obtaining ASecret key. ASecret is the key used to decrypt all the compromised files.

Share this:

Like this:

As promised, I’m writing a new post about Koler. This time I’ll talk about the communication between the mobile phone and the external domain because the malware makes use of a minimal C&C feature.
There are mainly two classes that are responsible of the interaction: com.android.6589y459gj4058rtgc.6589y459gj4058rtga and com.android.6589y459gj4058rtgd.6589y459gj4058rtgb. The flow of the program is guided by many conditional checks over some boolean flags. The flags are used to store the status of things like screen_is_off/screen_is_on/activity_is_stopped/etc.. I won’t put all these conditional checks in the analysis, because I want to write something as clean as possible focusing my attention to the client-server communication only; moreover it’s a detail you may easily check by yourself.

Everything starts from the run method of a thread (look inside com.android.6589y459gj4058rtgc.6589y459gj4058rtga), the client contacts the server passing a parameter to it. The parameter is an URI containing a string in this format: “random_string=mobile_phone_imei”. The random string len is 0x0A chars.

It returns null or a response string from the server. This is a standard piece of code used to get the reply from the server. Unfortunately I can’t dynamically check the response string because -fortunately- the domains are not working anymore. Luckily the run method contains a call to a method used to check the returned string. Let’s see if I can reconstruct the format of the response string.

The method is declared inside LockActivity and the declaration is:

public void 6589y459gj4058rtga(java.lang.String p1)

The execution of this method represents the end of the thread’s run, and since of this called method doesn’t return anything it’s likely to assume that something important could be inside it. The parameter is the response from the server.

Here’s the first information about the response string, it can be empty. From my previous article about Koler I know that FIND_VALID_DOMAIN is used to load one of the hardcoded domain page on the mobile phone browser. The page contains the ransom advice.
Ok, it’s time to understand what should happen when the response string is not empty. The first thing you’ll notice is the use of a specific resource:

Here we are: JSONObject. JSON is a simple data format used to exchange information between client and server. A new JSONObject is created with a parameter, it’s a string obtained from a Base64 decode operation over the response string. Now I know that the communication between server and client is encoded, and I can start imaging the format of a possible response string:

{ “field_1”:”val1”, “field_2”:”val2”, “field_3”:”val_3”... }

I don’t know what’s the real content of the decoded response string yet, but I could have an idea of what it looks like. The next snippet does a parse of the decoded string:

Here’s the current format of the response string passed to the client by the server:

{ “sign”=”base64_encoded_string” }

Another base64 encoded string, if the sign string is null the returned com.android.6589y459gj4058rtgd.6589y459gj4058rtga values is UNKNOWN.
Now, suppose sign is not null and the base64 decoding process is a success:

Here’s the final check over the UNKNOWN/UNLOCK value obtained from the response string. I already said what UNKNOWN means, it’s time to see what happens when UNLOCK tag has been received.
First of all there’s a check over the Json time field value passed from the server, if the current day is equal to the one specified by the server I got false into v0 and SET_UNLOCK-UNINSTALL messages are sent to the message handler. The day-check is done comparing the current day, month and year.
I didn’t say a lot about these two messages in the first part of the tutorial, it’s the right time to have a quick look at them:

SetUnlock lays the foundation and Uninstall provides to uninstall the package.

To sum-up, as far as I’ve seen UNKNOWN and UNLOCK are the only two commands from Koler’s C&C feature. The first one is used to show the ransom advice located on a domain web page. The other one -UNLOCK- *should* remove the malware from the system. I can’t be 100% sure because I’m doing a static analysis and I can’t test a real response from the server.

While I’m reversing a malware I usually use pen and paper to write down findings, no matter what’s the importance of any single clue. Sometimes it’s only a particular address or a handle, but for complex malware I like to draw a scheme with all the entities because it’s particularly useful when I have to put together all the small pieces to complete the final puzzle. I’ve seen malwares that are much more complicated than Koler, but the use of obfuscated names (Proguard is most probably used) increased the time I spent to understand everything .
In my humble opinion Koler is not so interesting per se, but it’s an advice of what a mobile malware could be in the near future. There are some nice descriptions around the web that are almost complete in terms of general functionalities. They all explain in few phrases the features of the malware:
– it sends the International Mobile Equipment Identity (IMEI) to a remote server
– open a browser page that displays a notice about the lock status of the device (in your language)
– claim to encrypt all the file inside the mobile phone
– ask for a ransom payment
– it somehow blocks the use of the device
– they all end with some tips on how to remove the trojan from the mobile phone
These are nice readings for sure because I like to be informed on every possible new threats, but I also would like to learn something new in terms of technical knowledge. My impression is that all of these articles are pretty similar, and they all seem to be born from what I know to be the first real article about the subject written by @kafeine.
I’m not asking for a complete analysis (it could require a lot of time and too many pages to write down), a detailed part on a specific argument or a personal comment about specific parts could be enough.

Since of there are a lot of Android components involved in the general scheme of this malware I decided to write a description of the methodology I used to statically studied the malware. It’s an easy level tutorial, but I hope to give you some hints on how to approach an Android malware directly working on components/entities like activities, services, receivers, message handlers, etc.
Apk SHA is 511993D3C99719E38A6779073019DACD7178DDB9.

Activity“An activity provides a user interface for a single screen in your application”. According to the image at the beginning of the post, there are only two objects that are not pointed by an arrow: MainActivity and BootStrapReceiver. What does it mean? Making the story short I can simply say that these are two different starting points of the application. Take a look at AndroidManifest.xml file:

Few lines to specify the activity to launch: com.android.MainActivity is the starting point of the entire package.
The manifest file is always the first thing you should put your hands on, it generally shows you the path to follow.

The activity contains a lot of methods, where do I have to start from? I normally start checking the init method because it does reveal the initial value of main variables. This is the very first method I use to check on a new class file to study. Besides that, there are an unspecified number of various methods, and some of them are callback methods called by the system when the activity switches from one state to another. These are really important, you have to take the activity life-cycle in your mind in order to better understand the complete behavior of the activity.

Activity life cycle (from developer.android.com)

MainActivity defines onCreate only, it’s called when the system is creating the activity. Besides the layout initialization (which is a must and it’s defined calling SetContentView function) a coder can do whatever he wants inside the method. This time OnCreate is the only defined callback. The reason is simple because the only job of the activity is to start a new activity named LockActivity, the real starting point of the malware.

startActivity is the function used to launch the new activity. The parameter of the function is an intent defined in the previous lines, it contains a little description of the operations to be performed:
– com.android.LockActivity contains the implementation of the activity
– set the action to be performed: it will display data to the user
– FLAG_ACTIVITY_NEW_TASK: the author wants to launch the activity into a new task

com.android.LockActivity
This new activity is by far different from MainActivity because it has a complete life cycle definition. Among all the methods you will find most of the callbacks that are on the activity scheme: onCreate, onStart, onResume, onPause, onStop and onDestroy. The first three methods are executed in sequence, here’s a brief explanation of them.

OnCreate: first of all it creates a new message handler class, after that it gets the IMEI and the buildID of the malware itself. To obtain the IMEI code it uses a method defined inside com.android.6589y459gj4058rtgk class:

It’s easy to get the buildID: C143D55D996634D1B761709372042474.
The last performed action inside the current method is to bind the service com.android.LockService. The bind operation is used to start a service, I’ll tell you later all the details about this operation.

onStart: it simply sets a flag. I call it StopFlag because the value is false when the activity starts and true on onStop.

What does it mean? Why can I see empty methods only? The class is just an interface and the code of each method is implemented inside another class. An easy search through the classes reveals where the real code is:

There are some other class defined as interface, now within few seconds you should be able to locate the real code of every empty class.

After onResume callback the activity is in a running status, and the flow depends on the behaviour of other entities like service, thread, human-operation, etc.
I can’t say too much about the other common callbacks: onPause, onStop, onDestroy. There are a lot of conditional checks over boolean variables because the author uses them to store the status of things like stop/run, pause/run and so on. I’m sure you won’t have problems trying to understand the code, just pay attention to the obfuscated names and you’ll surely understand everything about this class.

Message handler
LockActivity creates a new instance of com.android.6589y459gj4058rtgp class inside onCreate method, the class represents the message handler. How do I know it? The declaration gives a big hint:

It extends android.os.Handler. Moreover there are few methods only inside the class and all of them are called by a method called handleMessage, the name of the public method you have to subclass in case you want to receive messages.
A custom message handler class doesn’t have a life cycle like an activity or a service, you don’t have a specific entry point. I sugget to start the analysis from the subclassed methods, in this case handleMessage because it’s the only one.

Here is a brief analysis of handleMessage (in order to keep the code clean and readable I removed useless instructions/keywords from it).

UNINSTALL message has been received, it handles it by calling 6589y459gj4058rtgb. You’ll see this piece of code some more times inside handleMessage because there’s a check for every single type of possible received messages. The list of the available messages is composed by: UNINSTALL, CHECK_FOR_UNLOCK, SET_UNLOCK and FIND_VALID_DOMAIN.
The most interesting message is the last one because it’s called when the malware needs to load one of the hardcoded URL located inside arrays.xml file (it’s under res folder and it contains a complete list of available URLs).

WWW Thread
Here’s another entity created by LockActivity, it’s referenced by the class com.android.6589y459gj4058rtgc.6589y459gj4058rtga:

The class defines his own method and it implements some more methods. It also implements Runnable so, after init, I would check run method because it’s called when the thread is started.
There’s a data exchange between the external domain and the mobile phone. The malware provides to pass the IMEI (and the buildID) to the domain, and the domain sends back something else which is base64 encoded. As far as I’ve seen this is the only place from where crypto related functions are used. I will reveal the details about this part in a future blog post. Just in case you can mail me for some more details. However in the last part of the run method, after a series of calls to various methods, the web page containing the notice about the locked device is loaded on the infected mobile phone (via sendMessage(FIND_VALID_DOMAIN)).

Service via bindService
I introduced the Service component inside LockActivity, exactly when a bind operation was performed:

Three parameters:
service: the service to connect to, com.android.LockService
conn: it’s a valid ServiceConnection object (com.android.6589y459gj4058rtgt), and it declares two standard methods, onServiceConnected and onServiceDisconnected used to receive start and stop connection information
flag: BIND_AUTO_CREATE stands for automatic creation of the service.

According to Android web page a service is defined as an application component that can perform long running operations in the background and does not provide a user interface. A bound service runs only as long as another application component is bound to it.

Bounded service life-cycle (developer.android.com)

The image respect the fact that the service stays in background until unbindService is called. The scheme is very important for me, because it reveals the pah to follow for an almost complete analysis of the service. You have to study, in order: onCreate, onBind and finally onUnbind and onDestroy.

onCreate: this method is responsible of the creation of a system used to catch specific actions and broadcast particular intents. It sounds confusing right now, but everything will be clear in the next section.OnBind: nothing really special, it returns an Ibinder reference.OnUnbind/onDestroy: the client is not bound to the service anymore.

BroadcastReceiver
Here is another entity of the Android world, it’s basically defined to receive intents sent by sendBroadcast method. Intents broadcast are used to notify Broadcast Receivers. Once the intents arrive the onReceive method will take care of it. LockService’s onCreate defines a BroadcastReceiver in this way:

The receiver is registered with registerReceiver method. It takes two parameters, the BroadcastReceiver and the intents broadcast to be received.
The receiver is defined inside com.android.ScreenOnOffReceiver file and it has the only necessary method, onReceive. It handles the broadcasted intents checking for “android.intent.action.SCREEN_ON” or “android.intent.action.SCREEN_OFF” action.
As you can see from the snippet the intent filter is associated with a prority number which is used to check, among all the applications, who can send broadcasts.

Another interesting snippet in the same method, the purpose of this one is to set an alarm every 2 seconds after the first time. The action to perform when the alarm goes off is defined by a PendingIntent, com.android.ScheduleLockReceiver will handle the alarm. ScheduleLockReceiver’s task is to start LockService and it will make tough the use of your device…
Another similar piece of code is then used to define a new alarm every 10 minutes, this time the receiver is inside com.android.ScheduleUnLockReceiver but the essence doesn’t change.

There’s one more thing to say before proceed to the last section of this post. There are two ways to declare a broadcast receiver, one is statically and the other one is dynamically. I’ve shown you the dinamic version (via registerReceiver), and now it’s the turn of the other one. The static version requires few lines inside AndroidManifest.xml file:

To be sure the malware will run after a boot the receiver will start the core of the entire malware, LockActivity.
Once again, AndroidManifest.xml represents the first thing to take care of when you are studying an Android based malware.

Service via startService
Service once again? Yes, there’s something more to say about it.
Did you happen to take a look at the code of the receivers? Three of the four receivers have an almost identical code:

Is it possible to start a service in two distinct ways? Yes it is. There is a big difference with a bound service because now the service runs in the background indefinitely, no matter wether the component that started the service it’s destroyed.
The second line of the snippet contains a call to putExtra method, it’s a way to pass extended data to a service. Take a close look at ScreenOnOffReceiver, ScheduleLockReceiver and SheduleUnlockReceiver, you’ll notice that they all run the service using the same piece of code with just a little exception: the value passed via putExtra is 1, 2 or 3.

Unbounded service life-cycle (developer.android.com)

The image tells you exactly what to study. The only parts in common with a bounded service are intialization and finalization. I already know what’s inside onCreate/onDestroy so I’ve to get an eye inside onStartCommand. LockService class doesn’t have onStartCommand but onStart (which is deprecated since API level 5). The only interesting instruction inside the method is represented by the next one:

6589y459gj4058rtga(p1, p1.getIntExtra(6589y459gj4058rtgm, 0x00));

It calls 6589y459gj4058rtga with two parameters: the intent and the value of “start.event.type”. The int value is next used to understand who really runs the service and to perform specific operations:

Final notes
It’s definitely a not-complete tutorial, I just tried to give you the most important informations explaining how to deal with components and other Android entities. Consider it as a story on how I studied the malware. Feel free to mail me for comments/criticism/whatever you want.
Thanks to @Gunther_AR for some precious suggestions!

Like this:

Some months ago I did blog about a method I use to find out what’s behind hardcoded export addresses inside a disasmed file (it’s available at https://zairon.wordpress.com/2013/09/26/hardcoded-dll-export-address/). It works fine, but talking with a friend of mine I did realize that the entire process is a little bit mechanical. He told me about a possible configuration tool, just to ease the system. I finally had the time to create an Ida Python plugin based on his comments, it doesn’t fully respect what he had in mind but credit goes to Kayaker of course.

The zip file is available here and it contains two .py files: GetExportAddresses and APIAddressResolverPlugin (the gui based script):

GUI

This is the plugin dialog, and it’s used to configure everything. The idea is to have some directories, one for every OS files you are interested in. In the image you can clearly view I was dealing with XP_SP2 dlls. The control at the top of the plugin is used to select a specific directory, all the next operations will be done inside it. All the information about every dll are stored inside a single txt file named ExportAddresses.txt. The file is automatically created by the plugin itself when you select a directory without that file inside.

There are two listview controls inside the gui, the upper control lists all the available dll inside ExportAddresses.txt, the other one lists the exports inside a selected dll. The list view at the bottom is not really necessary indeed, but it can be usefull in case you need to have an idea about the addresses used by a specific dll.

To add a new dll you can use “Browse for a new DLL to add” button. You have to select a txt file created by GetExportAddresses.py, the other python file inside the zip. The file takes a dll as input and it produces a txt file with the information about the exported functions: the address of the function, the name of the dll and the name of the function.

To end the configuration process you only have to create the Python script able to check for the hardcoded address; just click on “Create GetExportedAddress.py” and the script will be created in the directory. With the use of this button you won’t have to change the path of ExportAddress.txt file each time you create a new OS dir. I haven’t added a script to re-solve all the possible hardcoded addresses because my idea is to solve few occasionally hidden addresses only.

It’s nothing special indeed, it’s handy in case you have to deal with different Oss and you don’t want to do all by hand.

Like this:

Two days ago I blogged about the approach I used to start analysing the malware, today I spent some more time on the target trying to get an idea of its behaviours. According to VirusTotal the file has a 21/51 revelation rate, it was 6/51 six days ago.
It has been designed for the Asian part of the world and, among all the malicious features, I noted an interesting data exchanges between the infected machine and a server behind 192.74.241.104/192.74.241.105 addresses.

From server to infected machine

Get

File plus.php is saved inside the infected machine. Wireshark marks the new file as an “application/zip” file, and I have to admit that at a first glance I thought the same thing:

Misleading header

I was wrong, the file is a not valid archive. To better understand what kind of file is this I put my hands on a debugger. All the bytes starting from offset 0x68 are decrypted by a simple piece of code:

It’s basically decrypted by an add operation, but the result is something I didn’t expect, here is a small part of the entire file:
The file is moved under “C:\Windows\System32\drivers\etc” directory with the new name hosts.ics. It seems to be the same list described inside three articles by Nshc Security. You can find the mentioned pdf report files inside the Red Alert Reports section:
– Internet Bank Pharming – BlackMoon
– Internet Bank Pharming with CVE-2013-3897
– Internet Banking Malware
The malware I’m checking has a lot of common things with the samples used to write the reports: it deletes antivirus exe related files, use a link file to run the malware at startup, create the hosts.ics file, steal certificates searching for NPKI folders sending them to a specific server in an encrypted format.
On the other hand the infection has slightly changed: dll file runs from rundll32 camouflaged into ctfmon.exe and not csrss.exe, start link has a different name V2LiteExp (the name comes from AhnLab V3 Internet Security suite), plus.php file is available in the recent samples only. Little things of course, but these are relevant in the removal process.

From infected machine to server

Send

A series of bytes are sent away, what’s behind this obscure sequence?
Again, a simple xor encryption is used to hide the real information to send. The message in clear view contains some strings revealing info about the infected machine and the infection itself:
– processor type, something like “Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz”
– physical free memory : “3584 MB”
– running OS: “Win XP SP2”
– date of infection: “20140415”
– location of hosts file: “http://192.74.241.104:805/plus.php”
These information are sent following a precise time line.

192.74.241.104 and 192.74.241.105
These addresses are under “PEG TECH INC” organization. There are many spam related complaints around the web from this organization, pay attention to 192.74.241.96/192.74.241.111 range addresses.
To end this post, look at the advice of a company named PegTech.

Here is a little story of how I approached the malware of the day, I hope to entertain you a little with this light post.

The malware is MFC based, and among all the sections there is one with a suspicious name: “.aspack”. It’s a good starting point, too bad the section is neither packed nor protected. The code is clear, but the strings are encoded using base64. It’s easy to recognize them due to their nature, some samples:Q3JlYXRlRGlyZWN0b3J5QQ==
Q3JlYXRlUHJvY2Vzc0E=
V3JpdGVGaWxl
RmluZFJlc291cmNlQQ==
All these encoded strings refer to API functions, and they are used by the executable following this precise scheme:

It decodes the name of the function and then it calls it. This piece of code is used to call all the functions requiring two arguments. What about functions with 1, 3 or more arguments? Well, the code is almost the same except few more push instructions before the call to the hidden function. At the end it turns out that the “.aspack” section was used to store these routines, I tried to give them understandable names:

The malware concept is pretty clear, the infection is done by a dropped dll. The name of the dll is random and its content comes from a resource item named “DAT” (the bytes are encrypted by a simple add-operation).ClearTraces routine is called at the end, it deletes the dropper using a curious method:cmd /c ping 127.0.0.1 -n 3&del <malware_file_path>
A sort of camouflage of del command.

I saved all these different snippets inside my Snippet Detector tool. I also added Base64DecodeString too because it often happens that the same encryption\protection_scheme is used inside the dropped files too.

If you carefully look at the routine names you’ll surely find out two almost obscure names:CUDiskMonitorApp__Modified_InitInstance
CUDiskMonitorApp__ExitInstance
The names come from various information I got browsing the net.

One of the first things I do when I start analysing a malware is to check the strings inside the target file. From all the encoded\decoded\clear strings I did focus my attention on this one: “dongchaomissyou@21cn.com”.
I started gathering some information from this e-mail address. Google reveals a lot of links in the search result, mostly related to Chinese language pages. There’s a person behind this address, he is/was one of the Evil Octal forum crew and he uses an MSN alternative address too: dongchaomissyou@hotmail.com
So, I tried to combine the forum name with the two mail addresses into a new web search and among all the possible links I stumbled on a page containing a VC++ project named UDiskMonitor. It’s a complete solution, it does contain the compiled exe, and it’s used to secretly copy the content of a new plugged device. I gave a glance at the package and it turns out that the malware author uses this pack as a base for his evil intention. The malware is completely based on this UDiskMonitor project, it’s pretty easy to recognize the same skeleton. There’s a fundamental difference btw, the malware author added what I named RunMaliciousDLL inside the InitInstance routine (it explains the name CUDiskMonitorApp__Modified_InitInstance).
With only few web searches I had the possibility to study a malware in a really short time, that’s not bad and I think you can now understand the importance of the external information!

The dropper calls only one exported function from the DLL: InitSkin.
First of all I tried my Snippet Detector, it’s able to recognize one of the functions I loaded from the previous exe:

Snippet Detector recognizes Base64 decode function

The DLL file uses the same base64 decoding routine, it means one thing only: strings are encoded.

Base64 encoded strings

There are a lot of hidden strings, and there’s another problem because the function names are encoded too:

Unknown calls

A lot of unknown functions. I wanted to decode all the strings obtaining a browsable disasm. Something like:
from: “100044D9 call dword_1004DEC4″
to: “100044D9 call __SystemParametersInfoA”
How to solve this problem? I decided to start from the Base64_Decode_String routine obtained from my tool. All the xref entries to this function come from two distinct kinds of snippets:

Snippet #2 is used on every string ending with “.dll”, snippet #1 for the others. The xref list is really long, do I have to reveal every single entry by hand? IDA offers a great script system but this time it’s not easy to write something able to solve the puzzle, especially because I have to decode base64 encoded strings. There’s another powerfull tool you can use: IDA Python script system. Here is the code of the .py file I wrote:

The idea is simple: I scan all the encoded strings, decoding and setting the name of specific addresses. The result is notable:

Before and after Python script

I didn’t limited my approach to the standard tools only (which are necessary of course), but using something else I had the opportunity to turn an unreadable deadlist into an almost fully browsable deadlist in a short time.

This is the end of the post, it’s not my intention to force you to use some specific tools; I’m just saying it’s hard to change habits but sometimes an excursus out of the usual path can be really convenient!

Directly from the main page of the challenge: “We created a special file to which a total of 10 flags are somehow related. All of them are easily recognizable once you find them, because they are of the form flag{xxx}, where xxx is a string made of ASCII printable characters excluding whitespaces.“

Ok, I have a file and I have to look for all these flags inside it!
The crackme is an exe file, protected by Upx.

ThisWasEasyToFind!
My first approach was to use a resource related tool: Resource Hacker. With few clicks I got my first flag: “ThisWasEasyToFind!”.

First flag and a possible hint for another flag

It was really easy indeed!

PNGdoesNotHaveExif,ButStilIIsFun
Looking at the image you can see the red ellipse, there’s a typo error but it doesn’t matter because it’s a new hint for an hidden flag. Resource hacker is unable to show the picture, it shows an error box with an advice about a possible compression of the resource. Trying the same thing with the unpacked crackme I got the same result, and I decided to inspect the two pictures with an hex editor:

Unpacked picture header on the left, original picture header on the right

In both case, the header doesn’t reveal recognizable image header, but the one on the left has an interesting bytes sequence: “7zXZ”. 7-Zip will open XZ file, it’s a PNG image and the header contains a new flag:

PNG header contains a new flag

Seems like the image was created with GIMP and the flag is: “PNGdoesNotHaveExif,ButStilIIsFun”.

JPEGalsoHasAFlag
Opening the image I got a surprise:

The picture flag

Another flag, “JPEGalsoHasAFlag”, the image was really interesting. A doubt remains, why jpeg and not png? Maybe it’s just an hint for those who didn’t see the image header at first. Anyway, it doesn’t matter.

DOSisPower
With the opened hex editor I decided to inspect the original and unpacked executables. There is an interesting thing inside the DOS Stub, the classic “This program cannot be run in DOS mode” phrase is not present this time. So, the only thing to do is to disasm (16 bit of course) the little snippet of 64 bytes starting from offset 0x40 of the executable:

RussianFlagItIs
Ok, I’m not able to get any other information from the hex editor, time to run the executable. A message box appears:

English and Russian language mixed together

The first time I run the program I didn’t notice the oddity included in the box. Well, once your eyes capture it you are on the path to the new flag! The caption of the box has a particular syntax, two words and one of them is inside ‘{‘, ‘}’ parenthesis. Time to inspect the code:

The caption is not a direct string but a sequence of bytes: 44 04 3B 04 30 04 33 04… These are the unicode codes for Cyrillic alphabet. i.e:
0x0444 is ф
0x043B is л
As soon as you have the complete conversion in Cyrillic (“флаг{РуссианФлагИтИс} “) you can use an online translator to view the new flag: “flag{RussianFlagItIs}” (I hope the translation is right…). Ok, I’m at half path, I need 5 more flags to complete the journey.

HowToFindStringsInPEYouKnow
Near the message box there’s a suspicious string: “ZmxhZ3tIb3dUb0ZpbmRTdHJpbmdzSW5QRVlvdUtub3d9Cg==”. His nature is pretty clear (look at the end of the string: ‘==’), base64 encoding was used. Here’s the proof: trying to decode that string I obtain the new flag: “flag{HowToFindStringsInPEYouKnow}”

YouKnowHowToDebugCode!
To find out the last four flags you have to get your hands inside the crackme code. Browsing throught the imported functions I have found an unusual entry, OutputDebugStringA. The function is called inside the code at 0x401770. The routine has 3 parts: message initialization, message decryption and OutputDebugStringA of the message. The message is created with a series of bytes except the last 8:

“changeme”, that’s an hint!
The decryption scheme is pretty simple, the first 5 bytes of the message are xored (byte by byte) with the first 5 bytes of the key “changeme”, the next 5 bytes of the message are xored with the first bytes of the key “changeme” and so on until 0x00 bytes is not reached. Pay attention because only the first 5 bytes of the key are used. The decrypted message is used as a parameter for OutputDebugStringA. The idea is to obtain the flag message, and it’s an easy task because the first 5 bytes of a general flag message are “flag{“. So, you have 5 bytes of the encrypted message (39, 47, 47, 46, 0A), 5 of the decrypted message (“flag{“) and you can find the 5 bytes of the key: 5f, 2b, 26, 21, 71. Here is the obtained flag: “flag{YouKnowHowToDebugCode!}”.

HaveNoFear,ConsoleFlagIsHere!
Another suspicious import inside the crackme is CreateToolHelp32Snapshot. We all know what it does and it deserves a deeper investigation because it’s used to show a new flag. The function at 0x401B42 is used to find a specific process: “cmd.exe”. The process should be running when you start the crackme, otherwise you won’t see the flag. The flag’s message is decrypted at runtime but you don’t need to study anything else, just look inside cmd console:

Cmd.exe flag

VeryGoodHardDriveName
The call that follows the one used to check cmd.exe contains the ninth flag, it starts from 0x401D78. Again, the right message is decrypted at runtime using a key of four bytes obtained by the result of crc32(GetVolumeInformationA). The crypted string begins with “E2 B1 A6 47..” hex values. The bytes of the crc32 value are used one by one inside the xor decryption. To find out the right crc32 value we got an help from the crackme itself, look at the final part of this call:

This is the check for the first five bytes of the decrypted message, but in order to obtain the right crc32 value I need the first four checks only.

E2 ^ 66 = 84
b1 ^ 6c = dd
a6 ^ 61 = c7
47 ^ 67 = 20

The crc32 value of 0x20c7dd84 is the right key for the current decryption and the new flag is “flag{VeryGoodHardDriveName}”.

RC4EncryptionIsFun!!!1
The last flag finally! To get the starting hint for this last flag I checked the output provided by Procmon, the crackme creates a system file named “decode.py” inside temp folder. It’s not a system file of course, it’s a Python script and here is the content of it:

Base64 plus RC4 decryption. Again, the printed text is somehow related to the flag message, so I know the first 5 chars of the text atleast: “flag{“. I didn’t waste my time trying to find a quick approach to the problem, I simply use one of the most stupid brute force approach. It returns more than one key but I was lucky to find the right one in a reasonable time. Here is the script: