Static Addresses, VirtualAlloc and Injected Processes

I have been recently working on updating bkdump.exe. The tool is a simple memory scanner that looks for memory marked as Read, Write and Execute (RWX) in processes. Version one would open up a dummy version of iexplore.exe using CreateProcess. Then scan the memory of iexplore.exe for any memory marked as RWX. If the memory is found it would dump it to a file. The new version can scan a specific process id (pid) and scan running processes of commonly injected processes such as firefox.exe,  iexplore.exe, chrome.exe and explorer.exe. As I have previously stated most of these concepts are not new. Many of these techniques have been implemented for detecting injected process in memory dumps for the Volatility project. I'll be releasing bkdump.exe in the next couple of days. I'd like to do some more testing. I'm new to C so I'm sure there will be some random quirks in my code but so far it's running and working.

During test cases of bkdump using families of malware I noticed something kind of interesting. A couple of families of malware can be detected by the size and allocated memory address of the injected process. Let's take for example Ramnit. I don't know how many version of Ramnit there are but I was able to identify five different variants of the injected process from 45 installers (Yes, the sample set is kind of small but my research machine is still packed up).  Let's check out a sample set of dumps from Ramnit installers that I was able to retrieve from VirusTotal Intelligence. The new version of bkdump can dump a process and save it to the working directory in the following syntax PID.0xAddress.bin. Below is the size and the file name.

Size          File Name                
36,864        1480.0x20020000.bin            
53,248        804.0x20030000.bin       
53,248        3944.0x20020000.bin       
53,248        3872.0x20030000.bin       
53,248        3788.0x20030000.bin       
53,248        3672.0x20030000.bin       
53,248        3276.0x20030000.bin       
53,248        3124.0x20030000.bin       
53,248        3000.0x20030000.bin       
53,248        2864.0x20030000.bin       
53,248        2804.0x20030000.bin       
53,248        2796.0x20030000.bin       
53,248        2776.0x20020000.bin       
53,248        2696.0x20030000.bin       
53,248        2600.0x20020000.bin       
53,248        2592.0x20020000.bin       
53,248        2520.0x20030000.bin       
53,248        2432.0x20030000.bin       
53,248        2268.0x20030000.bin       
53,248        1788.0x20030000.bin       
53,248        1476.0x20030000.bin       
53,248        1028.0x20030000.bin

57,344        528.0x20020000.bin       
57,344        3820.0x20020000.bin       
57,344        3452.0x20020000.bin       
57,344        3228.0x20020000.bin       
57,344        3068.0x20020000.bin       
57,344        2420.0x20020000.bin       
57,344        2148.0x20020000.bin       
57,344        156.0x20030000.bin   
135,168        3100.0x20020000.bin       
102,400        552.0x20020000.bin       
102,400        444.0x20020000.bin       
102,400        3832.0x20020000.bin       
102,400        3316.0x20020000.bin       
102,400        3220.0x20020000.bin       
102,400        3052.0x20020000.bin       
102,400        2816.0x20020000.bin       
102,400        2644.0x20020000.bin       
102,400        252.0x20020000.bin       
102,400        2456.0x20020000.bin       
102,400        2436.0x20020000.bin       
102,400        2020.0x20020000.bin       
102,400        1792.0x20020000.bin       
102,400        1496.0x20020000.bin   

Notice a recurring pattern in the size and address? If we open up the installer in Ollydbg and set a breakpoint on VirtualAlloc we can see why.

Ramnit is allocating memory at that address space. Let's change that value to from 20020000 to 200F0000. Now we can see it allocating memory at that specific offset in the injected process.

That didn't go very well. Basically what is happening is the programmer designed this variant to have a static base address of 0x02002000.  Here are the sizes and the allocated addresses of the ones I found.

Size     Address
36,864  0x20020000
0x20020000, 0x20030000
57,344  0x20020000
135,168 0x20020000
102,400 0x20020000

Let's check out stats from some Zeus samples. Sorry for the different layout of the data. Old set.

Count - Size
12 - 159744
02 - 139264
01 - 102400
01 - 106496
02 - 208896
01 - 163840
03 - 090112
01 - 249856
01 - 217088
01 - 155648

Count - Address
20 - 0x024a0000
01 - 0x024d0000
04 - 0x016a1000
01 - 0x016a0000
01 - 0x025c0000

Addr: 0x024a0000 Size:159744
Addr: 0x024a0000 Size:159744
Addr: 0x024d0000 Size:139264
Addr: 0x024a0000 Size:155648
Addr: 0x024a0000 Size:139264
Addr: 0x016a1000 Size:102400
Addr: 0x016a0000 Size:106496
Addr: 0x024a0000 Size:208896
Addr: 0x024a0000 Size:159744
Addr: 0x025c0000 Size:159744
Addr: 0x024a0000 Size:208896
Addr: 0x024a0000 Size:163840
Addr: 0x024a0000 Size:159744
Addr: 0x016a1000 Size:90112
Addr: 0x024a0000 Size:159744
Addr: 0x016a1000 Size:90112
Addr: 0x016a1000 Size:90112
Addr: 0x024a0000 Size:249856
Addr: 0x024a0000 Size:159744
Addr: 0x024a0000 Size:159744
Addr: 0x024a0000 Size:159744
Addr: 0x024a0000 Size:159744
Addr: 0x024a0000 Size:159744
Addr: 0x024a0000 Size:217088
Addr: 0x024a0000 Size:159744

Kind of interesting.  I should have bkdump version 2 out in the next couple of days. Feel free to shoot me an email, leave a comment or ping me on twitter if you have any questions, comments or job offers :)

1 comment:

  1. Hey man good stuff. Interesting stats.
    I was actually in the works of coding something similar; scan memory regions for RWX.. Just for learning experience. Anyways keep up the good work.