Site icon Marco Ramilli Web Corner

How To Unpack Malware: Personal Notes

Nowadays malware authors use a lot of techniques to hide malicious payloads in order to bypass security products and to make malware analyst life harder and fun. There are many tools that you can use to extract content from malware and there is not a standard process, you can use different tools, different techniques and different approaches to solve the same problem.

During this post I am going to quickly describe three (well, actually kind of four) of the main flows that takes me in succeed to unpack malware. But let me repeat that there are many ways to perform such a topic, I simply want to share some personal notes on my favorite flows, without pretending to write a full course material on how to Unpack Malware, which it worth of a full university class.

NB: there is a lot to say about packers, how they are, how they behave, there is much to say even on how many packers family are known, but this is not the place for that. What I am doing here is to mostly focusing on quick shot-cuts useful when you are on rush but not such powerful as debugging the entire process.

Method 0: Just Unpack It, I don’t care more

Well, if you are on rush and you just need to try to unpack a sample as quickest as possible, if you don’t care about what is going on, well Sergei Frankoff (@herrcore) and Sean Wilson (@seanmw) did a great job in releasing Unpac.ME. A web application that tries to unpack your sample, there is a limited free plan for using it, it works most of the times especially with known malware families

Method 1: The quick way

One of the quickest way to simply unpack malware is to try to figure out what packer has been used to pack your sample. Once you have the used packer you just need to run the relative un-packer and that’s it, you have done. Detect it Easy or bettern known as DiE would help you in performing such research. It has a wide signature database tracking hundreds different packers. The following image shows DiE spotting a simple (and very didactic, not really real) UPX packer.

Once you know it has been packed through UPX 3.91, just go and grab the used packer (in such case go to https://upx.github.io/) take the relative unpacker and run it against your original sample, you would see a new PE file.

Method 2: The slow but fun way to do !

This is my favorite method since it’s definitely faster than using debug and performing every step by yourself but quite powerful as well getting you the control of many actions happening into memory. Before going into this method you need to know the following main assumptions.

  1. The packer would performs some operations on bytes (read from external file or from the same file or taken from the network) then it will aggregate such a bytes and later on it will pass execution flow (EIP) to those bytes. We call those bytes the “payload“.
  2. Injecting control flows is the main strategy used by packers.
  3. Intercepting the injection flow will abstract us from the used packer

It is now interesting to understand how injection happens on Windows machine. Once we nailed it, we would agree that a quick way to unpack malware is just to grab content from the allocated and injected memory before the main sample (or stub) will make a change of control by passing EIP and Stack to new code.

Main Injection techniques to look for

Fortunately there are not thousands of different possibilities to inject shellcode into memory, so let take a closer look to the main ones. The most used is named process injection.

The process injection schema follows these main steps:

Image from HERE

Another very used technique is the DLL Injection which follows these steps:

Image from HERE

Process Hollowing is a nice and very used trick to evade endpoint security and to inject control floes. The main idea is to build a suspended process within un-mapped memory. Then replace the un-mapped memory section with the shellcode and later on map and start the process. The steps follows:

Image from HERE

Abusing the Asynchronous Procedure Call (APC) is another way to inject shellcode into processes. The way to exploit this Microsoft functionality follows theses teps:

Figure from HERE

The last method that I’am going to describe in my personal notes (but there are many more out there) is called: Process Doppelgänging. Quite a recent technique it uses a very little known API for NTFS transactions.

Briefly speaking, we can create a file inside a transaction, and for no other process this file is visible, as long as our transaction is not committed. It can be used to drop and run malicious payloads in an unnoticed way. If we roll back the transaction in an appropriate moment, the operating system behaves like our file was never created.

hasherezade

The process Doppelgänging is a similar technique used to inject control and to evade common AV. It follows these steps:

All these methods are useful to inject payload into memory and to run them keeping a very low rate of detection. Our goal is to intercepts those techniques and to dump the just injected paylaod.

Intercepts these techniques and drop the payload

Now we know the main techniques used by malware to unpack themselves into memory, so we are ready to understand how to hook such functions in order to grab the payload (holding the real behavior). Again there are many techniques to perform that memory extractions, I did change at least 4 workflows until now, but the one I prefer so far is using PE-sieve (download from HERE) to extract injected objects. PE-Sieve is not able to judge the dropped file (are they malicious or not?), so you cannot consider every extracted artifact as a malicious one, you rather need to manually analyze them and express your own assumptions on them.

But let’s start with a practical example. The following image represents a PE file pretending to be a PNG image.

A PE sample pretending to be a .PNG

Looking for sections and import table (IAT) we might observe the samples imports only some of the well-known functions we ‘ve just seen in the previous section (VirtualProtect, GetProcAddress, MoveMemory, etc..) and very often used to unpack malware in memory without touching hard-drive.

Import Table

Even the embedded resources are quite “heavy” which would probably hide some piece of code (??). So … we have a PE file which pretends to be an image, it only imports suspicious functions and it has got a quite heavy resource. Would it be a Malware ?

Looking at resources

Well we do have ideas and suspects but let’s see if it injects pieces of code into the memory and let’s see what they do. Here PE-sieve comes to help us. First of all you need to sacrifice a system :D. Yep, really… you need to run on your target the sample and on the other side you need to run pe-sieve by giving the PID of the suspicious sample. PE-sieve will hook and monitor the previous injection patterns and as soon as it find the right pattern it will drop whatsoever (good files, malicious implant, etc etc) the sample injects. The following image shows the found implants running that sample.

2 Implanted Objects

The dropped files are placed into a directory named with the monitored PID.

Dropped Files

We get some files into that directory. We do have .json report in order to automate results and to wrap them into external projects without using the provided PE-sieve.dll. We have a couple of shellcode (.shc) and three PE. Interesting the 400000.cursor.exe since has 600KB of code and it is executable, and a new ICO different from the original one. Let’s check it’s own property (following image)

Unpacked Property

Now, let’s roll back our scarified VM and run this new file on it. Now let’s check its memory to see if something more is happening there.

Memory from Unpacked one

It looks like we have clear text, no additional encryption/packing stage as shown in memory. We now can follow with classic malware analyses techniques by staging static and dynamic analysis. And, yes, since you are re-scarify your virtual machine, let maximize your effort to grab network traffic and see where it tries to communicate with.

Traffic Analysis

We are facing a nice example of TrickBot version: 1000512 tag: tot793 . The following image shows the same information but coming from the internal systemcall rather then network traces.

Internal Traces

So we nailed it. We’ve just extracted the real payload and later on we figured out it was a TrickBot.

Method 3: The old fashion way (debugger)

Everything can be done from the debugger. You can find the above API patterns by yourself and then follow the System calls and stop and copy whenever you want. you can extract or modify the sample behavior on fly and decide to re-run it as many times you need. Yes, you can, but this would take you a lot of time. Time runs against the economy. More time you need to perform your anlaysis more expensive you are, more expensive you are less customers you could have in both ways: money-wise (expensive = for few ~ cheap = for many) and time-wise (sine you have 24h a day, after that hours you cannot accept more customers). So you would need to mediate between quality/fun and time.

If you are following me since time you would probably remember that I was used to this method years ago, before such a great tools were realized (just few examples: IDA Pro Universal Unpacker or All In Memory CryptoWorm or New way to detect Packers etc..) but today I would not suggest you this method unless you are a student or not a professional Malware analyst.