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
53,248 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 :)
Subscribe to:
Post Comments (Atom)
Hey man good stuff. Interesting stats.
ReplyDeleteI was actually in the works of coding something similar; scan memory regions for RWX.. Just for learning experience. Anyways keep up the good work.