Malware Analysis with OllyDbg
In this part of the article series, we will look how we can look at the inner workings of a malware. In part 1 and part 2 we have worked on the behavioral analysis of the specimen. In this article, we will look at the code level of specimen discussed in Part 2.
We will be using OllyDbg and load the specimen into it. As soon as the specimen is loaded, let’s take a look at the Names(kind of strings, imported functions, etc.). Below is a snapshot of Names window in ollydbg for this specimen.
Nice we see references to ReadFile and CryptDecrypt. This looks like specimen is trying to read some file and also call Windows decryption function. If you recall, we saw an encrypted version of a .tmp file in Part 2. To see if our understanding is correct or not, let’s see ReadFile references
Then follow it in the disassembler.
Below what we can see is the ReadFile reference in the code.
We need to look at what is ReadFile reading, so we need to place a breakpoint at this statement. After placing a breakpoint, we ran the sample and below are the contents of the stack.
As per Microsoft ReadFile function documentation, hFile is “A handle to the device (for example, a file, file stream, physical disk, volume, console buffer, tape drive, socket, communications resource, mailslot, or pipe).” This means this is a pointer to a file. Let’s look at the handles and see what does this handle resolves to:
Bingo, this is what we were expecting it to read the .tmp file. However, the content of this .tmp file is encrypted, and thus we do not know what malware is doing in the underlying system. Remember we have seen a function call CryptDecrypt which might reveal the content of this .tmp file.
Find out CryptDecrypt function(easy way is to go to Names window > look for references and then follow in disassembler). Below is the CryptDecrypt function, we need to see what this function returns, so we will place the breakpoint in the instruction right after the cryptdecrypt function where the function is checking for the value in eax and make a respective jump.
Why eax? Because eax holds the return value of the function and as per Documentation of CryptDecrypt, if the function succeeds then the function returns a non-zero value, which is exactly our case.
Looking at the stack for these, we find out the following ASCII text. Remember ads.php? Yeah, it was the URL the specimen was trying to ask through a GET.
These are the indeed the contents of the .tmp file. However, since our web server does not hold any ads.php, the specimen was not able to complete the action or receive any command back from the server. We will get around this, but first, we need to decode the response from the specimen which we saw earlier that it is encrypted. In the above URL, we see a parameter encode=5b which might be the key; the author is using to obfuscate the contents.
It is common to find out the author using one-byte key in algorithms like XOR, ROT, ROR, etc. If you remember, we have saved the content previously but for a quick recap below are obfuscated content that we need to de-obfuscate.
We will first convert the file into raw and then use a utility translate.py with ‘byte ^ 0x5b’ to decide the content.
moreover, we found below in decodedtest.txt
Ok, so we now know that the malware is enumerating the system for running services. However, how is this triggering? If we remember we saw the below in .tmp file
It looks like malware is trying to get away with some command signatures and is using cexe as an alias for exec, tixe as an alias for the exit, etc. Since the malware is looking for ads.php, we will create repsctive page in our web server stub.
As per our assumption, cexe is an alias for exec so it should use an executable path as argument. This will be command passed through ads.php to the specimen to execute it in the system. We created this page on our web server.
Then we ran the sample and routed the traffic using fakedns. We observed following packets
Moreover, as expected, malware start launching calc.exe in the host at an interval of 30 secs(sleep=30000).
So that is it: we built up a good number of IoCs and had a good understanding of the working of the malware specimen now. To reiterate, we need to work step by step and give malware what it needs and then analyze the outcome of the action.