Well I wanted to post another article about memory forensics with my favorite open source tool right now…. Volatility. Can’t say enough great things about the documentation (very well written and expansive) and the community is very helpful in answering questions (even noobish ones). So after I read MHL’s Stuxnet Analysis with Volatility 2.0 it inspired me to do my own sort of analysis with a different piece of malware to see how many artifacts I could come up with. I’ll be referencing some in-depth deep dives to confirm the analysis. At the end of the article the links will be given to those reports in full. I’m going to assume no prior knowledge is known about Zeus. We can use Volatility to start as well as confirm with multiple artifacts we are in fact infected with Zeus beyond any doubts.
Luckily for us we don’t have to infect a VM, take a memory dump and then analyze it (or have a friend ask for our help to cleanup their computer like here). The folks at Volatilityhave provided a sample image that’s infected with Zeus for you to practice on. They are in need of contribution with additional malware if you have any laying around that you’d like to share. So download the image and follow along.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem imageinfo
Volatile Systems Volatility Framework 2.0
Suggested Profile(s) : WinXPSP3x86, WinXPSP2x86 (Instantiated with Win
XPSP2x86)
AS Layer1 : JKIA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (C:\RE\volatility2.0\py\volatility-2.0\zeus.vmem)
PAE type : PAE
DTB : 0x319000
KDBG : 0x80544ce0L
KPCR : 0xffdff000L
KUSER_SHARED_DATA : 0xffdf0000L
Image date and time : 2010-08-15 19:17:56
Image local date and time : 2010-08-15 19:17:56
Number of Processors : 1
Image Type : Service Pack 2
So we can tell this is a XP SP2 image, no big surprise here. Let’s grab a process listing.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem pslist
Volatile Systems Volatility Framework 2.0
Offset(V) Name PID PPID Thds Hnds Time
---------- -------------------- ------ ------ ------ ------ -------------------
0x810b1660 System 4 0 58 379 1970-01-01 00:00:00
0xff2ab020 smss.exe 544 4 3 21 2010-08-11 06:06:21
0xff1ecda0 csrss.exe 608 544 10 410 2010-08-11 06:06:23
0xff1ec978 winlogon.exe 632 544 24 536 2010-08-11 06:06:23
0xff247020 services.exe 676 632 16 288 2010-08-11 06:06:24
0xff255020 lsass.exe 688 632 21 405 2010-08-11 06:06:24
0xff218230 vmacthlp.exe 844 676 1 37 2010-08-11 06:06:24
0x80ff88d8 svchost.exe 856 676 29 336 2010-08-11 06:06:24
0xff217560 svchost.exe 936 676 11 288 2010-08-11 06:06:24
0x80fbf910 svchost.exe 1028 676 88 1424 2010-08-11 06:06:24
0xff22d558 svchost.exe 1088 676 7 93 2010-08-11 06:06:25
0xff203b80 svchost.exe 1148 676 15 217 2010-08-11 06:06:26
0xff1d7da0 spoolsv.exe 1432 676 14 145 2010-08-11 06:06:26
0xff1b8b28 vmtoolsd.exe 1668 676 5 225 2010-08-11 06:06:35
0xff1fdc88 VMUpgradeHelper 1788 676 5 112 2010-08-11 06:06:38
0xff143b28 TPAutoConnSvc.e 1968 676 5 106 2010-08-11 06:06:39
0xff25a7e0 alg.exe 216 676 8 120 2010-08-11 06:06:39
0xff364310 wscntfy.exe 888 1028 1 40 2010-08-11 06:06:49
0xff38b5f8 TPAutoConnect.e 1084 1968 1 68 2010-08-11 06:06:52
0x80f60da0 wuauclt.exe 1732 1028 7 189 2010-08-11 06:07:44
0xff3865d0 explorer.exe 1724 1708 13 326 2010-08-11 06:09:29
0xff3667e8 VMwareTray.exe 432 1724 1 60 2010-08-11 06:09:31
0xff374980 VMwareUser.exe 452 1724 8 207 2010-08-11 06:09:32
0x80f94588 wuauclt.exe 468 1028 4 142 2010-08-11 06:09:37
0xff224020 cmd.exe 124 1668 0 ------ 2010-08-15 19:17:55
Nothing immediately stands out to me as they all look like legitimate processes that are running on the box. Let’s see if any of them are hiding with a new command fresh out of 2.0 which is psxview.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem psxview
Volatile Systems Volatility Framework 2.0
Offset Name Pid pslist psscan thrdproc psp
id csr_hnds csr_list
0x80fbf910L svchost.exe 1028 1 1 1 1
1 0
0x80ff88d8L svchost.exe 856 1 1 1 1
1 0
0xff1d7da0L spoolsv.exe 1432 1 1 1 1
1 0
0x80f60da0L wuauclt.exe 1732 1 1 1 1
1 0
0xff2ab020L smss.exe 544 1 1 1 1
0 0
0xff3667e8L VMwareTray.exe 432 1 1 1 1
1 0
0xff247020L services.exe 676 1 1 1 1
1 0
0xff217560L svchost.exe 936 1 1 1 1
1 0
0xff143b28L TPAutoConnSvc.e 1968 1 1 1 1
1 0
0xff203b80L svchost.exe 1148 1 1 1 1
1 0
0xff1b8b28L vmtoolsd.exe 1668 1 1 1 1
1 0
0xff255020L lsass.exe 688 1 1 1 1
1 0
0xff3865d0L explorer.exe 1724 1 1 1 1
1 0
0xff22d558L svchost.exe 1088 1 1 1 1
1 0
0xff374980L VMwareUser.exe 452 1 1 1 1
1 0
0xff1fdc88L VMUpgradeHelper 1788 1 1 1 1
1 0
0xff218230L vmacthlp.exe 844 1 1 1 1
1 0
0xff364310L wscntfy.exe 888 1 1 1 1
1 0
0x80f94588L wuauclt.exe 468 1 1 1 1
1 0
0xff25a7e0L alg.exe 216 1 1 1 1
1 0
0xff1ecda0L csrss.exe 608 1 1 1 1
0 0
0xff38b5f8L TPAutoConnect.e 1084 1 1 1 1
1 0
0xff1ec978L winlogon.exe 632 1 1 1 1
1 0
0xff224020L cmd.exe 124 1 0 0 1
0 0
0x810b1660L System 4 1 1 1 1
0 0
This uses multiple methods for looking at processes artifacts in memory. If you see any that are 0’s for psscan, pslist and thrdproc it’s an attempt to hide the process by DKOM (Direct Kernel Object Manipulation). Nothing interesting here so let’s see about some network connections.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem connections
Volatile Systems Volatility Framework 2.0
Offset(V) Local Address Remote Address Pid
---------- ------------------------- ------------------------- ------
Well that’s disappointing. No active connections at the time the memory dump was taken. Let’s go a little deeper and scan for connections that may have been previously closed with connscan.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem connscan
Volatile Systems Volatility Framework 2.0
Offset Local Address Remote Address Pid
---------- ------------------------- ------------------------- ------
0x02214988 172.16.176.143:1054 193.104.41.75:80 856
0x06015ab0 0.0.0.0:1056 193.104.41.75:80 856
Bingo! We have 2 connections here that look to be listed to PID 856. That’s SVChost which is odd. Let’s see where these connections are located. A whois report reveals that the IP is located in Moldova.
IP Address | 193.104.41.75 |
Host | 193.104.41.75 |
Location | MD, Moldova, Republic of |
City | -, – – |
Organization | PE Voronov Evgen Sergiyovich |
ISP | PE Voronov Evgen Sergiyovich |
It’s well known that a lot of malware calls Eastern Europe and Asia home. So this is pretty suspicious but since it looks like all our processes appear legitimate we might be facing some malware that utilizes code injection. To detect these types of processes MHL has released a great plugin here that utilizes malfind. It will detect injected processes so let’s run that on our target image.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem malfind --dump-dir c:\re\zeus_demo
VMwareTray.exe 432 0x00d70000 0xd95fff00 VadS 0 PAGE_EXECUTE_R
EADWRITE
Dumped to: c:\re\zeus_demo\VMwareTray.exe.4be97e8.00d70000-00d95fff.dmp
0x00d70000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............
0x00d70010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ……..@…….
0x00d70020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
0x00d70030 00 00 00 00 00 00 00 00 00 00 00 00 d0 00 00 00 …………….
0x00d70040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 ……..!..L.!Th
0x00d70050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is program canno
0x00d70060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 t be run in DOS
0x00d70070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 mode….$…….
VMwareTray.exe 432 0x00e30000 0xe30fff00 VadS 0 PAGE_EXECUTE_R
EADWRITE
Dumped to: c:\re\zeus_demo\VMwareTray.exe.4be97e8.00e30000-00e30fff.dmp
0x00e30000 b8 35 00 00 00 e9 cd d7 ad 7b b8 91 00 00 00 e9 .5…….{……
0x00e30010 4f df ad 7b 8b ff 55 8b ec e9 ef 17 3e 76 8b ff O..{..U…..>v..
0x00e30020 55 8b ec e9 95 76 39 76 8b ff 55 8b ec e9 be 53 U….v9v..U….S
0x00e30030 3a 76 8b ff 55 8b ec e9 d6 18 3e 76 8b ff 55 8b :v..U…..>v..U.
0x00e30040 ec e9 14 95 39 76 8b ff 55 8b ec e9 4f 7e 3c 76 ….9v..U…O~<v
0x00e30050 8b ff 55 8b ec e9 0a 32 3a 76 8b ff 55 8b ec e9 ..U….2:v..U…
0x00e30060 7d 61 39 76 6a 2c 68 b8 8d 1c 77 e9 01 8c 39 76 }a9vj,h…w…9v
0x00e30070 8b ff 55 8b ec e9 c4 95 c8 70 8b ff 55 8b ec e9 ..U……p..U…
Disassembly:
00e30000: b835000000 MOV EAX, 0x35
00e30005: e9cdd7ad7b JMP 0x7c90d7d7
00e3000a: b891000000 MOV EAX, 0x91
00e3000f: e94fdfad7b JMP 0x7c90df63
00e30014: 8bff MOV EDI, EDI
00e30016: 55 PUSH EBP
00e30017: 8bec MOV EBP, ESP
00e30019: e9ef173e76 JMP 0x7721180d
00e3001e: 8bff MOV EDI, EDI
00e30020: 55 PUSH EBP
[snip]
Well we have a lot of output so looks like a lot of our processes are injected with malcode. The reason this plugin can find it is due to the fact of looking for kernel memory structures that work very closely with VirtualAlloc. These memory structures are in a VAD tree and work closely with memory management aspects of the kernel. There’s a lot more detailed explanation in the references section if you care to read further on the subject. The plugin outputs hexdumps as well as assembly code at the base location of where the injected code was detected. You can also pipe this output to a text file if it won’t fit in your console.
With all this output from our plugin let’s revisit our pstree command so we can get a hierarchical view on how the code injection may have cascaded.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem pstree
Volatile Systems Volatility Framework 2.0
Name Pid PPid Thds Hnds Time
0x810B1660:System 4 0 58 379 1970-01-
01 00:00:00
. 0xFF2AB020:smss.exe 544 4 3 21 2010-08-
11 06:06:21
.. 0xFF1EC978:winlogon.exe 632 544 24 536 2010-08-
11 06:06:23
... 0xFF255020:lsass.exe 688 632 21 405 2010-08-
11 06:06:24
... 0xFF247020:services.exe 676 632 16 288 2010-08-
11 06:06:24
.... 0xFF1B8B28:vmtoolsd.exe 1668 676 5 225 2010-08-
11 06:06:35
..... 0xFF224020:cmd.exe 124 1668 0 ------ 2010-08-
15 19:17:55
.... 0x80FF88D8:svchost.exe 856 676 29 336 2010-08-
11 06:06:24
.... 0xFF1D7DA0:spoolsv.exe 1432 676 14 145 2010-08-
11 06:06:26
.... 0x80FBF910:svchost.exe 1028 676 88 1424 2010-08-
11 06:06:24
..... 0x80F60DA0:wuauclt.exe 1732 1028 7 189 2010-08-
11 06:07:44
..... 0x80F94588:wuauclt.exe 468 1028 4 142 2010-08-
11 06:09:37
..... 0xFF364310:wscntfy.exe 888 1028 1 40 2010-08-
11 06:06:49
.... 0xFF217560:svchost.exe 936 676 11 288 2010-08-
11 06:06:24
.... 0xFF143B28:TPAutoConnSvc.e 1968 676 5 106 2010-08-
11 06:06:39
..... 0xFF38B5F8:TPAutoConnect.e 1084 1968 1 68 2010-08-
11 06:06:52
.... 0xFF22D558:svchost.exe 1088 676 7 93 2010-08-
11 06:06:25
.... 0xFF218230:vmacthlp.exe 844 676 1 37 2010-08-
11 06:06:24
.... 0xFF25A7E0:alg.exe 216 676 8 120 2010-08-
11 06:06:39
.... 0xFF203B80:svchost.exe 1148 676 15 217 2010-08-
11 06:06:26
.... 0xFF1FDC88:VMUpgradeHelper 1788 676 5 112 2010-08-
11 06:06:38
.. 0xFF1ECDA0:csrss.exe 608 544 10 410 2010-08-
11 06:06:23
0xFF3865D0:explorer.exe 1724 1708 13 326 2010-08-
11 06:09:29
. 0xFF374980:VMwareUser.exe 452 1724 8 207 2010-08-
11 06:09:32
. 0xFF3667E8:VMwareTray.exe 432 1724 1 60 2010-08-
11 06:09:31
We did notice that services.exe looked to have some code injected into it. Let’s take the parent process (winlogon.dmp that was dumped by malfind) and submit it to virustotal as PID 676 seems to be where the code injection is originating from in a hierarchical sense.
Sure enough 26/44 say it’s malicious. Seems most of the scans detect it as Zbot. So let’s Google around find some reports and see if we can verify it’s presence elsewhere. Now that we’re armed with some reports let’s verify some other artifacts on the system just to make sure this is Zbot.
“The install function searches for the “winlogon.exe” process, allocates some memory within it and decrypts itself into the process.”
Well what do you know it looks like Zbot/Zeus injects it’s code into winlogon.exe This was apparent after we did our malfind as it detected injected code into other processes. If you would use procexedump through volatility it would be fine if you submitted to an avscan as it uses the pe header to dump the memory image. The new code sections that were allocated and later written to will not be reflected in the original pe header that was loaded into memory. This is the exact reason why we had to use malfind (Thanks again MHL!) above and couldn’t just procdump based on pid.
“The bot executable is written to the hard drive as “C:\WINDOWS\system32\sdra64.exe”.”
Volatility has a useful plugin here that allows us to identify file handles that are still hanging around in memory filescan.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem filescan
Volatile Systems Volatility Framework 2.0
Offset(V) Obj Type #Ptr #Hnd Access Name
0x01090778 0x8109d560 1 0 R--r-d '\\WINDOWS\\system32\\winrnr.dll'
0x010915b0 0x8109d560 1 0 R--rwd '\\WINDOWS\\system32\\oleaut32.dll'
0x01091648 0x8109d560 1 0 R--rwd '\\WINDOWS\\system32\\rpcrt4.dll'
0x01091810 0x8109d560 1 0 R--rwd '\\WINDOWS\\system32\\csrss.exe'
0x01092270 0x8109d560 1 1 RW-rw- '\\WINDOWS\\WindowsUpdate.log'
[snip]
0x029d9b28 0x8109d560 1 1 R----- '\\WINDOWS\\system32\\sdra64.exe'
0x029d9cd8 0x8109d560 1 0 -WD--- '\\WINDOWS\\system32\\sdra64.exe'
[snip]
“The directory “C:\WINDOWS\system32\lowsec\” is created. This directory is not visible in Windows Explorer but can be seen from the command line. Its purpose is to contain the following files:
local.ds: Contains the most recently downloaded DynamicConfig file.
user.ds: Contains logged information.
user.ds.lll: Temporarily created if transmission of logs to the drop server fails.
”
These artifacts can also be found in the above file scan to further bolster the case that this is definitely Zeus.
“The Winlogon (“HKLM/SOFTWARE/Microsoft/WindowsNT/CurrentVersion/Winlogon”) registry key’s value is appended with the path of the bot executable: C:/WINDOWS/system32/sdra64.exe. This will cause the bot to execute when the computer restarts.”
Volatility sure enough has a feature to allow us to investigate registry entries. Namely the printkey command. So let’s check the reg key from our Zbot analysis to see that this is here too.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem printkey -K "Mi
crosoft\Windows NT\CurrentVersion\Winlogon"
Volatile Systems Volatility Framework 2.0
Legend: (S) = Stable (V) = Volatile
----------------------------
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\software
Key name: Winlogon (S)
Last updated: 2010-08-15 19:17:23
Subkeys:
(S) GPExtensions
(S) Notify
(S) SpecialAccounts
(V) Credentials
Values:
REG_DWORD AutoRestartShell : (S) 1
REG_SZ DefaultDomainName : (S) BILLY-DB5B96DD3
REG_SZ DefaultUserName : (S) Administrator
REG_SZ LegalNoticeCaption : (S)
REG_SZ LegalNoticeText : (S)
REG_SZ PowerdownAfterShutdown : (S) 0
REG_SZ ReportBootOk : (S) 1
REG_SZ Shell : (S) Explorer.exe
REG_SZ ShutdownWithoutLogon : (S) 0
REG_SZ System : (S)
REG_SZ Userinit : (S) C:\WINDOWS\system32\userinit.exe,C:\WINDOWS\
system32\sdra64.exe,
REG_SZ VmApplet : (S) rundll32 shell32,Control_RunDLL “sysdm.cpl”
REG_DWORD SfcQuota : (S) 4294967295
REG_SZ allocatecdroms : (S) 0
REG_SZ allocatedasd : (S) 0
REG_SZ allocatefloppies : (S) 0
REG_SZ cachedlogonscount : (S) 10
REG_DWORD forceunlocklogon : (S) 0
REG_DWORD passwordexpirywarning : (S) 14
REG_SZ scremoveoption : (S) 0
REG_DWORD AllowMultipleTSSessions : (S) 1
REG_EXPAND_SZ UIHost : (S) logonui.exe
REG_DWORD LogonType : (S) 1
REG_SZ Background : (S) 0 0 0
REG_SZ AutoAdminLogon : (S) 0
REG_SZ DebugServerCommand : (S) no
REG_DWORD SFCDisable : (S) 0
REG_SZ WinStationsDisabled : (S) 0
REG_DWORD HibernationPreviouslyEnabled : (S) 1
REG_DWORD ShowLogonOptions : (S) 0
REG_SZ AltDefaultUserName : (S) Administrator
REG_SZ AltDefaultDomainName : (S) BILLY-DB5B96DD3
Well that key is certainly apparent and this is our persistence mechanism. So the Zeus/Zbot injector process is called at start-up to insert it’s hooks and malicious code in our legitimate looking processes to evade detection. This would be something you’d want to clean up if you were re-mediating the system as well.
“The Windows XP firewall is disabled. This causes a Windows Security Center warning icon to appear in the system tray, the only visible indication that the computer has been infected.”
It looks like Zeus/Zbot also takes care of disabling the Windows Firewall so your not annoyed with any popups while it’s pilfering through your banking data. Googling around there are some registry forensics blogs that keep track of the location for windows firewall settings. Using our command printkey we can detect if this is enabled or disabled in this specific image.
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem printkey -K "Co
ntrolSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile"
Volatile Systems Volatility Framework 2.0
Legend: (S) = Stable (V) = Volatile
----------------------------
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\system
Key name: StandardProfile (S)
Last updated: 2010-08-15 19:17:24
Subkeys:
(S) AuthorizedApplications
Values:
REG_DWORD EnableFirewall : (S) 0
So the firewall is currently disabled and if you notice the timestamp on the key as well. It looks like this was last updated at 2010-8-15 at 19:17:24. This is tidbit of information that you could use in a timeline analysis if you had to document to this level of detail. The specific Zeus/Zbot may not modify this key every time but check if its set according to it’s specifications. I’m not sure as I don’t have the file but it would be a reasonable assumption. Also the EnableFirewall key was not in the DomainProfile but only the StandardProfile for you registry pros out there.
“A closer look at its binary file reveals that the spyware was designed to monitor known ZBOT mutexes, _AVIRA_ and __SYSTEM__.”
C:\RE\volatility2.0\py\volatility-2.0>python vol.py -f zeus.vmem mutantscan
Volatile Systems Volatility Framework 2.0
[snip]
0x05ca17e8 0x810ae5e0 2 1 1 0x00000000 '_AVIRA_2108'
[snip]
Well there is certainly a mutex that has been recent in memory for AVIRA which ironically enough is the name of an antivirus engine. It was sent to poke fun at the anti-virus companies by the programmer’s of Zeus. It also looks from the above mutex that we have a 1.x version of Zeus/Zbot as in 2.x versions they use randomly generated GUID’s over mutexes to communicate.
So there we have it using Volatility we can get a look at a Zeus/Zbot infection and determine steps here for possible remediation just based on a memory dump. We’d have more resources if we were able to have access to the system as well so we could study the injector process to see if it has any other persistence mechanisms. It’s doubtful since this matches so closely to the typical Zeus/Zbot signature. I hope you enjoyed reading this article!
Edit: Looks like another Zeus article was written and is linked here to give you another viewpoint on this piece of malware.
References:
[1] – http://www.fortiguard.com/analysis/zeusanalysis.html
[2] – http://www.dfrws.org/2007/proceedings/p62-dolan-gavitt.pdf
[3] – http://www.eptuners.com/forensics/contents/examination.htm
[4] – http://www.sans.org/reading_room/whitepapers/malicious/clash-titans-zeus-spyeye_33393
[5] – http://www.symantec.com/connect/blogs/brief-look-zeuszbot-20