fredag 22 juli 2016

Analyzing H1N1v2: Battle injection and dynamic imports in search of configs

While analyzing H1N1v2 I found myself using some methods that I can't remember having read about anywhere in terms of analysis, so I figured I might as well do a short write-up about it. Nothing revolutionary, but hopefully useful. A summary on H1N1v2 itself can be found on Kernelmode and analysis results have been published by Arbor.


Getting imports

As stated in the post above, the loader consist of two parts, the loader responsible for loading the second part, the actual payload responsible for communicating with the C2 server and perform any tasks retrieved from the C2 server. The sample used can be found on Malwr.

H1N1 is "crypted" and can be found in the resource section, XOR-encoded using a key ZIOUFAIOjf.




Static analysis of the "uncrypted" executable show that their isn't a import section. This by itself is suspicious and suggest that imports are resolved at runtime, making static analysis hard.

H1N1 resolves all imports for each module; first imports from kernel32 and then ntdll. The imports themselves are resolved by hash which eliminates the need for strings. Getting the base address for the modules are also resolved by hash.

The functions for getting the base address is the first call in the "main" function. The value moved to EBX just before the call looks very similar to a hash-like value, and inspecting the function confirms that this is indeed a "resolve by hash" function.






Before the next function is called, ESI and EDI have addresses moved to them, these are pointers to the destination IAT and an array of hashes that represent the imports to be resolved.

So it's resolving imports, and? As the original executable don't have imports on disk, static analysis would be a problem that much is clear. However since H1N1 resolves all the imports for each module it's possible to dump the imports to disk after they have been resolved. This would enable much faster static analysis and identifying interesting functions.

The weapon of choice is ImpRec. Using the "IAT Autosearch"-function would yield nothing which means that we must manually located the IAT which can be done by following any of the resolved imports in memory. Using the RVA from the IAT ImpRec is able to find the resolved imports, although with quite some invalid thunks.

By cutting away the invalid thunks (Show invalid) the result will be something like:




After fixing the original file with the imports the executable can be opened in IDA and the code will become much more easy to analyze.




This technique will be re-used later on when the final payload is retrieved. Up to this point the loader-part of H1N1 can be analyzed statically using IDA. I won't go into detail on how it works in this post.


Battle process injection

The loader is responsible for injecting its payload into another process, namely explorer.exe in this case. The loader creates a new suspended process and creates a new shared section which holds the payload code. Before the section is mapped into explorer.exe the loader will write code to the entrypoint, this is an excellent place to manipulate the code to make sure that we don't lose control over execution when the process is allowed to continue.




To be able to control the execution inside explorer.exe after the loader calls ResumeThread, a pause is needed, this can be done a couple of different ways, I've opted for the "EB FE"-approach (jump-to-self).

Before the code is copied it needs to be patched which can be done by following ESI (pointing to the source) and patching the two first bytes with EB FE.




The result would be that explorer will enter an infinite loop after ResumeThread is called. By attaching to the explorer process and replacing "EB FE" with the original two bytes we now have control over the execution of the injected code. The first thing that will happen is again that the base address for kernel32 will be located and imports resolved, the interesting part in this code is a couple of instructions further down from the entrypoint.




This is a loop that will decode something using simple XOR. Following EDI when entering the loop will show the progress as the loop executes. The end result is an executable which is the payload of H1N1.


Fix payload IAT and decode strings

 

After unpacking the Upack layer the entrypoint is again very familiar. As this is the actual payload, there will more than just imports from kernel32 and ntdll as there need to be imports used to communicate with the C2 server. Therefore there is some work to be done.

After having resolved the imports from kernel32 there is one import that is of special interest namely LoadLibraryA, without having a specific module loaded the imports can't be resolved. So a good idea is to fix the imports for the current state (after kernel32 imports have been resolved) and look up xrefs in IDA for LoadLibraryA which gives an idea where to look:





One function stands out, and looking at this function in IDA would reveal that there are not only a number of calls to LoadLibraryA but also calls to a function that resolves imports for each loaded module. One way to go about this would be to backtrack how execution ends up at this place, however, as the function doesn't have any dependencies from arguments passed upon being called, it can be called directly

So after having resolved kernel32 imports, a new origin can be set at the first instruction and the function can be executed until it returns. Several modules will be loaded and imports be resolved. At this point the IAT can be dumped from memory using the same approach as earlier which would give us a chance to make sense of the code in IDA.





At this point there is enough to get an understanding of the execution flow and what the different functions does in the payload. After following some imports and strings I end in a function that decode kind of a long string, well actually two strings. The beauty here is that the same technique can be used to decode the string as resolving the external imports, setting a new origin that is.





As VirtualAlloc will allocate the memory used for decoding the strings, the allocated memory can be followed during the execution which would give not only the C2 servers but also the encryption key:


The destination address of the encryption key was changed to show both in the same image.


Summary

H1N1 presents some interesting challenges while trying to find the config and non the less all the steps which are required to get to this point. This post is a combination of analysis findings but also a hint of tricks that can be used to get a better understanding of malware that is obfuscating for example imports and strings. When it comes to strings I highly recommend reading the article on analyzing Dridex by MalwareTech.

Again, H1N1 have been analyzed previously and published by Arbor, however, I wanted to shed some light on how the results could be achieved but also how to handle dynamic imports and process injection.

Inga kommentarer:

Skicka en kommentar