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.