The stuxnet malware has been making the press recently for two reasons. First it contains two drivers signed with a legitimate (at the time) cert. Second is it's targeting SCADA systems. The malware is cool for a host of other geeky reasons. Nick Harbour, Stephen Davis, and I started looking at the malware Sunday afternoon. We had hoped to write a blog post about the specifics of the malware before we left for Vegas on Friday. However, in the short term I thought this malware would provide a great opportunity to demonstrate how memory analysis can be leveraged to find malware easily, and how the MANDIANT's Indicator of Compromise editor (IOCe) tool can be used to describe the malware and what to look for.
The goal of every good IOC is to leverage the intelligence we have about the malware to find it effectively, while allowing for changes/ variants, and weeding out false positives. We can describe most aspects of malware using the IOC language, for this exercise we will focus our energy on writing a good memory IOC. In memory, malware appears rather naked and this is a prime example of that. When loaded, stuxnet spawns lsass.exe in a suspended state. The malware then maps in its own executable section and fixes up the CONTEXT to point to the newly mapped in section. This is a common task performed by malware and allows the malware to execute under the pretense of a known and trusted process. The first indicator in memory is the path it uses to spawn lsass.exe:
Notice that the path to lsass.exe has extra backslashes so when the backslashes are resolved by CreateProcessW the path is c:windows\system32\lsass.exe instead of c:windowssystem32lsass.exe. This is seen in the following screen shot taken from Audit Viewer:
Notice the arguments in each process. The process with a score of 100 is the original lsass spawned by the system. The process with a score of negative 145 is the lsass spawned by the malware. The arguments are very distinctive and a great indication that something is wrong. This is a fine IOC for this specific variant but fixing this and rendering the IOC useless is a trivial task for this malware author. So let's keep building out the IOC.
If we examine the lsass process further we see another indicator that something is wrong.
Above is a complete DLL listing of the malicious lsass. Who can spot what is missing? If you noticed the lsass.exe itself is missing you are correct. The original lsass has about three times the number of DLL's and also includes lsass.exe in the listing:
The listing continues but notice lsass.exe at the top. The lack of a binary and DLLs in the malicious lsass listing reconfirms what we already knew. That the malware used a process suspend and unmap technique. When the attacker unmaps the lsass.exe section, the lsass.exe is removed the VAD tree and subsequently doesn't show up when doing a DLL listing based on VADs. Spotting suspend and unmap via taskmgr or other live response tools would be very difficult. In this case the malware author took extra care and created the process with the correct privileges allowing the attacker to mimic the correct lsass.exe user.
The next addition to the IOC is the digital signature itself. The drivers were signed and verified:
The file is signed and the signature was verified.
Realtek Semiconductor Corp
VeriSign Class 3 Code Signing 2004 CA
We can use the fact that this certificate has now been revoked and add this to our IOC. This again is not a great variant resistant IOC because the attacker can sign their driver with a new cert, if they have one, or have an unsigned driver. In either case those changes will render this IOC useless. We will still add it to our existing IOC knowledge base.
The next behavior to create an IOC for is the injection component. Stuxnet injects at least one binary into svchost, lsass, services and we see references for the potential to infect winlogon as well. Stuxnet is actually injecting a full binary not just shellcode into these processes.
When we examine the inject sections we see the binaries import three dlls:
The most abstract way to write an IOC for this is to say any process that has an injected binary that imports ADVAPI32.dll or KERNEL32.dll or USER32.dll flag as part of the stuxnet malware family. There is a chance we could end up flagging other things as part of stuxnet but adding imports makes the IOC a little too strict. This is a much better signature the previous two. It allows for some modification and requires the author to actually make more than one line code changes in their malware to force us to miss it. Now it's still feasible that the malware could be modified and we could miss it with the current three IOC's we have so let's continue building our IOC. The final thing to create an IOC for is the rootkit component. The rootkit component is designed to hide the presence of the malware and LNK file on the filesystem. To do this they use an old standard technique that AV and rootkits have been using for years. The rootkit layers itself on filesystem devices, if you are running on VMWare it will layers itself on the VMWare filesystem driver. If we create an IOC describing the driver layering we can make it very hard to defeat detection. The IOC we create states that any driver that layers itself on sr.sys, fs_rec.sys, and fastfat.sys will be flagged. There is definitely a chance for false positive but it should be a small set of hosts and you can add parameters to exclude the false positives if need be. This IOC could be expanded if you are running truecrypt or other filesystem software the IOC might need to be updated or modified to include or exclude certain drivers. IOC's can and should be tailored for the environment where necessary. The final memory IOC looks like this:
Lets translate this IOC into english. If a process with an argument that contains \system32\lsass.exe OR a driver exists that has a certificate subject that contains Realtek Semiconductor Corp flag it as stuxnet. OR a driver exists that has attached to the following fs_rec.sys AND sr.sys AND fastfat.sys flag the driver as part of stuxnet. OR a process has an injected section AND the injected section imports any of the following DLLs advapi32.dll OR kernel32.dll OR user32.dll. This is a pretty solid IOC for malware in memory as we do more work on the malware we may find more nuisances we can add to it, this is a good start.
Our focus here was to describe the malware in memory using an IOC. But when we write IOCs for the field or customers we take everything into account including disk, registry, filesystem, eventlog, etc. A more complete IOC for this malware looks like:
This IOC reads the following way if the file has a section named .stub OR a file exists named mdmcpq3.pnf OR a file exists named mdmeric3.pnf OR a file exists named oem6c.pnf OR a file exists named oem7a.pnf OR all of the following drivers are attached to by one drivers fs_rec.sys, sr.sys, fastfat.sys OR a process has an injected section AND it imports any of the following DLLs advapi32.dll, kernel32.dll, user32.dll OR a file exists named mrxcls.sys and it has a certificate subject of Realtek Semiconductor Corp OR a file exists and it has a name of mrxnet.sys and it has a certificate subject of Realtek Semiconductor Corp OR a registry key path exists of HKEY_LOCAL_MACHINESYSYTEMControlSet001ServicesMRxCLsImagePath AND has a value of mrxcls.sys OR a registry key path exists of HKEY_LOCAL_MACHINESYSYTEMControlSet001ServicesMRxNetImagePath AND has a value of mrxnet.sys.
Nick Harbour, Stephen Davis, Jamie Butler, Kris Harms and I will all be at Blackhat this year teaching classes ranging from Malware Analysis Crash Course, Advanced Malware Analysis, Advanced Memory Analysis in Incident Response, and Incident Response. Even if you don't take a class, join us for the MANDIANT pre-game party from 7-9 on Wednesday before going out for the night!