After I took an initial look at the emotet-dll I in Part 1 I now want to get a bit more into the details off what is going on exactly. This part will cover some of the things I tried and found out. Keep in mind, most of what I am writing down could be wrong or lead to the wrong result. I am simply sharing my thoughts and ideas and results off each session, until I am fairly certain to know what the malware is doing at each point.
Before I am going to continue with the code, lets see if those dlls we got are the same or differ in some parts. After hashing all files and sorting for uniques I ended up with 3 different files. For starters I will only compare 2 of those against each other.
You can not see it here, but the files are nearly similar and only differ in a few different function calls (names). We could investigate further here and check for any interesting differences but I decided to skip this for now.
Lets take a look at the imports now and check for any interesting functions. I expected an empty IAT but found a „relatively normal looking“ executable. Other than the usual imports we have „pdh.dll“ which imports a few interesting functions which I think is normally used for working with performance counters but may be abused at some point. I am not sure though and have to look into that.
The others are nothing I did not expect. Interesting side note though, all the imports we can see are referenced by name EXCEPT Oleaut32.dll which is referenced by ordinal for some reason. I guess this will become clear later on…
The exports are obfuscated as we have already seen. The only clear export is „Control_RunDLL“ which is usually used to run control panel items (.cpl). This is an undocumented function of the shell32.dll which is also included in the imports and therefore likely a good indicator. Even better that we already know that we are dealing with rundll32.exe which is also used with .cpl files and likely something that should be investigated further.
At first the sections do not stand out. We have .text, .rdata, .data, .rsrc and .reloc sections.
The .rdata, .rsrc and the .reloc section have high entropy and seem to be packed. Furthermore, the .rdata section seems to hold some form of encrypted code? Could this be some form of encryption scheme? Looking at the .data section there is also a hint that C-libraries are implemented somehow.
Up next are the resources and here we have 7 resources included that we could dump directly. None of those look interesting at first except the string „ass“…Not sure what to make of that. The others are either seemingly random or obfuscated. This could obviously be code that will get used later on but could also be nothing at all.
Looking at the strings does not reveal anything that was unexpected at this point. We have some strings hinting at registry-functions, strings that correlate with working with files and working with threads and other usual stuff.
Run it again!
Now, without going too much into detail I ran the file again with the known arguments via rundll32.exe C:\ProgramData\1457673244.dll,f103901943 and set a few breakpoints at Registry-Functions, File-Operations, Process-Operations and GetProcAdress. Now, the whole operation was (at least according to what I know so far) not really interesting. The file loaded a few libraries modified its own code called GetProcAdress a few times and then jumped back to the Entrypoint. The interesting part (so far) is the call to CreateProcess where the file called itself again with another Argument:
Now, this confirms that the Control_RunDLL is the actually important call which does the heavy lifting. I suppose that the file then checks for ParentProcess, cmdline/argument or anything that checks the arguments and where its coming from. Looking at the Control_RunDLL function again we see one call to „sub_10006550“ and then one „jump if zero“. If zero (green) the Program will probably end. Probably because I am not sure how the code looks like at runtime and what this or-operation actually does. It seems to actually „decrypt“ the value of whatever is returned from the first run with the seemingly random argument such as f103901943. If we look at the other obfuscated functions we can see that a seemingly random value is moved into eax. This seems to be some form of control mechanism in the form of:
1. run dll from macro-document with random generated argument
2. loop through the whole executable until we get to Control_RunDLL as argument
3. Actually start with the interesting part
If not zero (red) then the execution will continue at EAX which will contain the offset aControlRundll_1. For now this is all I can get from this function. Some serious debugging is needed here…
The only function we could check that may tell us something is the one I already mentioned in the last part. Sub10006550 looks like some form of decryption. If we check the X-refs to this function then this seems to be plausible as all the other obfuscated functions link to the Control_RunDLL and then from there link to sub_10006550.
Now run it for real!
Ok, enough theory…if we actually run the file and let it run without interruption then it will do nothing. This was about to be expected. I found several calls to GetTickCount64 and NtQueryInformationProcess. Those are known anti-debug-functions used to…well…stop someone debugging your stuff 😉 I could go ahead and patch out (NOP or just modify the cmp or jmp/je) and therefore bring the execution on the right track or just use a plugin like scyllahide (there are others) and patch out the anti-debug-functions not wanted. This worked and simply executing the program results in another rundll32.exe-process with an unknown parent process. The file is then shortly afterwards already busy contacting the internet (not shown here) and moving files. This seems to be the actual last stage or one of the last.
One of the indicators is another seemingly random folder in C:\Windows\SysWOW64\ with a seemingly random filename.
Persistence is then created by installing itself as a service in registry.
The dropped executable is – as expected – the same as the one we got from the macro document.
Without jumping to any conclusions…I am certain that I have the basic workflow of the malware down. I did not write down the urls and ips I found so far because I am certain that there are more of them inside. With this in mind it should be easier to narrow down a basic workflow and rule out things that are either decoy or not necessary to analyze…which I will do in the next part 😉