Pony stealer: a malware analysis - The sample analysis - Part three

After the first two parts here and here, we can move forward giving the sample a run inside a disassembler to look what's inside and, eventually, into a debugger to see it live.

IDA has some difficulties to analyze the sample due to the facts it heavily uses anti-disassembly trick:

Note that the conditional jump to 41062E never gonna happens. We can patch those bytes \xF8\x72\x01 with NOP instruction or leave them alone knowing the fact that IDA can be fooled during analysis. Also at 41062F the sample delays its execution, invoking GetTickCount function and dividing the remainder of the DIV instruction by a predefined constant. So until the CMP instruction is satisfied it will run this bunch of code a pseudo-random number of times. It appears that this technique can trick some antivirus heuristic controls.

After condition is verified, the flow reaches the CALL instruction at 4105c3, we see another anti-disassembly technique, the misaligned PUSH instruction.

Clearly the misaligned PUSH at 4105c7 is there to fool the disassembler and we need to fix it if we want to have a better look on that piece of code. By defining manually that byte at 4105d0, IDA can now better analyze the code:

Now it's clear what this piece of code does: it pushes the address of the function at 4105a2 onto the stack. This pointer will be the argument of SetUnhandledExceptionFilter function that, in the end, will exit from the process in case of unhandled exception.

Let's focus on what happens at address 410508, because it's where the fun starts:

After some studies I tried to interpret that code and the results are shown below.

Basically malware is starting its activities: first it loads libraries with the OleInitialize and LoadLibraries calls, after it fires up a delayer routine that, in malware intentions, will fool the heuristic controls of Kaspersky Antivirus. After that it enable some required privileges with the fourth call:

This routine will cycle through and enable all these privileges:

And after that it tries to get if the process is running within LocalSystem or not. In both cases it will impersonate or the LocalSystemUser or the LocalUser using the API call to GetUserNameA.

In the next session we'll go deeper into the analysis trying to better understand its codebase.