Unpacking KOVTER Malware
Sample:
40050153DCEEC2C8FBB1912F8EEABE449D1E265F0C8198008BE8B34E5403E731
Behaviour analysis
this malware uses a highly sophisticated way of unpacking, I’ll be demonstrating how to fully unpack it and extract the second stage of it.
let’s start by dynamically analysing this sample, fire up ProcMon and execute the sample.
after capturing events with ProcMon, save it to a CSV file and load it to ProcDot, it will look like this.
this is a lot of output!, what we need to focus on are the red colored event.
we see that it dropped a file to disk.
and also some weird registry keys created.
let’s first start by navigating to that dropped file’s directory.
we see two files one of them is a .bat file and the other has a random extension .2ed62.
- note: batch files are scripts that contains multiple commands to be executed by the command line in Windows.
let’s view the batch file’s contents.
Registry Activities
the start command will open this file d031.2ed62 but what is the file actually is?. this file is not even an executable, after some time I realised that this is just a dummy file and the actual purpose is not to execute it.
Windows by default when it tries to open any file, it looks for the software that can run the file in the registry, what we can do now is to open the registry and look for the software or command that executes .2ed62 extensions.
you can find a list of extensions under HKEY_CURRENT_USER\Software\Classes
we found the extension but what is the value 0346?, it is supposed to hold the name of the software that will open it.
this 0346 is just there for obfuscation purpose and it acts like a pointer (means that you can find it in the list of extensions).
going down the list of extensions we can see our pointer and it points to mshta.exe followed by a JavaScript code to execute.
double click on the name and extract the whole command.
What pops up into our eyes immediately is the registry key HKCU\\software\\gxyhwinsg\\zbrqoytjz. it reads the contents and store it in V0ZOG variable, then calls eval function which will execute the script (it needs to be a JS script). So let’s examine what’s in that key.
This time if we tried to just double-click it, it won’t work because of the length.
We can use reg_export command line tool instead.
command:
reg_export HKEY_CURRENT_USER\Software\gxyhwinsg zbrqoytjz dumped_scp.js
the script we extracted looks very hard to analyse, a good thing to start with is to try searching for any evals.
and indeed near the end of the code we can see an eval, why is this important?
as we can see this code has alot of numeric data stored which can be another form of JS scripts that is being decoded and executed.
eval is a the function that will execute any JS script, so rather than spending time analysing the code (which will be a big pain), we can simply reach the point
that it calls eval (obviously after decoding the payload) and just examine what is passed to eval.
how can we do that?
patching JavaScript code
One of the quick ways is to patch eval and make it print the code to us.
append this code to the top of the script:
oe = eval
eval = function(i){
WScript.Echo(i);
oe(i);
}
run the script with wscript.exe.
we got what it seems to be some base64 encoded data, let’s copy and decode it.
- note: you can’t copy directly from windows script host, so a good way to get this string is to open:
Process Hacker
wscript.exe Process [go to strings].
find the encoded string and extract it.
PowerShell Analysis
after extracting the script, we open and see a reference to powershell.exe at the end of the script.
that means after decoding the base64 data we’ll find a powershell script.
and yes, it is a powershell script, let’s move on to our windows machine and analyse it.
there is a great tool called powershell_ise to debug powershell scripts, let’s use it to open our script.
opening the script in powershell_ise we can see a variable called sc32 at line 26 that holds a set of hex values.
and at line 28 we see a VirtualAlloc invoked to allocate the length of sc32 with 0x40 (READ_WRITE_EXECUTE).
and if we take a look at line 32 and 34 we see that it copies the bytes from sc32 to some memory pointer then calls CreateThread to execute that region of memory.
So, what we can conclude from this basic analysis?
- this powershell script is just another loading stage to load and execute the shellcode in sc32 (the name also tells us that this is a shellcode [shellcode32]).
let’s dump this shellcode and analyse it, don’t go too far, we can also use powershell_ise to extract this shellcode.
first we need to put a breakpoint in the line after sc32 variable (rigth-click and toggle breakpoint).
run the script (it will break after 15 seconds because at the beginning of the script it sleeps). after you hit the breakpoint type this in the bottom console.
[io.file]::WriteAllBytes('shellcode.bin',$sc32)
Shellcode Analysis
and now we have our shellcode set and ready for analysis. let’s start analysing from SCDbg tool.
click launch and observe the output.
nothing intersting, we can see that it only open some registry keys (which are not presented because this shellcode is not loaded in memory so it can determine strings based on his address) and thats it, we have to dynamically analyse it in order to know what it is essentially doing.
let’s use runsc tool.
as we see in the console, we need to open XDBG and attach runsc process then put a breakpoint on the shellcode’s address.
after you put the breakpoint, go back to the runsc window and click any key once or twice untill you hit the breakpoint in XDBG.
we are now in the shellcode code!.
from our previous analysis we see that this sample calls RegOpenKeyExA but take a note that if you do a bp RegOpenKeyExA the breakpoint wont trigger because this function is actually loaded from advapi32.dll
so type the following in the XDBG console:
bp advapi32.RegOpenKeyExA
run.
and YES! we hit it, and as we see from the stdcall window, we know the key it opens.
let’s get back to user code, if we scrolled down a little we can see a call to RegQueryValueExA (makes sense because we called RegOpenKeyExA) and VirtualAlloc.
let’s put a breakpoint on VirtualAlloc and watch the memory that it allocates (the return memory address is in EAX).
run again and observe how this memory region changes.
we hit another VirtualAlloc and our memory was filled with some random data. follow the second VirtualAlloc’s return address in dump and run.
WE GOT THE UNPACKED EXECUTABLE!
WHAT A LONG JOURNEY!!