Malware Persistence without the Windows Registry
Written by Nick Harbour
For an attacker to maintain a foothold inside your network they will typically install a piece of backdoor malware on at least one of your systems. The malware needs to be installed persistently, meaning that it will remain active in the event of a reboot. Most persistence techniques on a Microsoft Windows platform involve the use of the Registry. Notable exceptions include the Startup Folder and trojanizing system binaries. Examining malware persistence locations in the Windows Registry and startup locations is a common technique employed by forensic investigators to identify malware on a host. Each persistence technique commonly seen today leaves a forensic footprint which can be easily collected using most forensic software on the market.
The persistence technique I’ll describe here is special in that it doesn’t leave an easy forensic trail behind. A malware DLL can be made persistent on a Windows host by simply residing in a specific directory with a specific name, with no trace evidence in the registry or startup folder and no modified system binaries. There isn’t just one directory location and DLL filename that are candidate locations for this persistence mechanism but rather a whole class of candidate locations exist for any given system. On my laptop (Windows 7 64-bit) there are no less than 1032 such path and DLL name combinations where a DLL could be placed such that it would automatically be loaded at some point during my normal boot-up, and that’s just for a 32-bit DLL! If you had a 64-bit malware DLL the number would be much higher as I have many more 64-bit processes running at boot time. So how does this work?
DLL Search Order Hijacking
When an application requests to load a DLL either statically via an import table in its executable file, or dynamically via the LoadLibrary() function the operating system will look for the DLL in a predefined sequence of locations. This sequence is defined in the MSDN documentation here: http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx. The most important tidbit of information to take away from that document is that the first place the application looks for a DLL is the location of the executable itself. This isn’t always the case though. If the DLL name that is requested is listed in the “\\.\KnownDlls” object then it will always load from a fixed location (the System32 folder). This object is populated at boot-time using data from the Registry at the following location:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs
Microsoft employee Larry Osterman describes this in a blog post (http://blogs.msdn.com/b/larryosterman/archive/2004/07/19/187752.aspx). He states in the post that the KnownDlls object will be larger in memory than what is in the Registry key and will be built recursively from the statically imported DLLs from any DLL listed in the registry. In the limited testing I’ve done on Windows XP and Windows 7 systems, the KnownDlls object in memory is identical to the list provided by the KnownDLLs registry key.
Casual browsing of the KnownDlls key will reveal a short list of about 30-35 of the most commonly used DLLs. For example, the low level networking API DLL “ws2_32.dll” is contained in this list. Whenever any application attempts to load a DLL named “ws2_32.dll” it will always load it from the System32 folder because it is listed in this key, regardless of where the application was launched from. The KnownDlls system provides a thin layer of security for this small set of crticial DLLs because an attacker can’t simply place a DLL named “ws2_32.dll” inside a folder containing an application which uses ws2_32.dll and expect their local copy to be loaded. The KnownDlls system is far too limited to provide any realistic sense of DLL loading security though. For example, even though we can guarantee that the copy of ws2_32.dll that will be loaded will always be the one from system32, other components loaded when ws2_32.dll is loaded (such as iphlpapi.dll and mswsock.dll) are not guaranteed because they are not covered by KnownDlls.
Lets imagine that we had a legitimate program called update.exe which ran from the location “C:\Program Files\MyCompany” and loaded ws2_32.dll, all we would have to do to make update.exe load our malware DLL is place our malware in the “C:\Program Files\MyCompany” directory and give it the name “iphlpapi.dll”. When the update.exe program runs it loads ws2_32.dll, which in turn loads iphlpapi.dll which it loads from the application directory first before checking the System32 folder where it legitimately resides. All the malware author needs to do is make sure their malicious iphlpapi.dll eventually loads the real thing and the user of the system (and a forensic analyst most likely) will have no idea that malware has been loaded.
Real-World Usage
You might have come to the conclusion in reading the description of the problem above that executables which reside in the System32 folder are not susceptible. If you thought that, you’d be correct. If you also thought that there is no real practical problem because all consistent and reliably placed startup binaries exist in the System32 folder, you’d be incorrect. Case-in-point: Explorer.exe . Strangely, this binary resides in C:\Windows (I assume for historic reasons). So when explorer.exe launches and it requests a DLL that is not protected by KnownDlls, the first place the system looks to find the DLL is the C:\Windows directory. Thus far, the most common place we’ve found this malware persistence technique being used is in the location and name “C:\Windows\ntshrui.dll”. The real ntshrui.dll is located in the System32 folder but since this dll is loaded by Explorer.exe and not protected by KnownDlls, it’s unfortunately susceptible to DLL search order hijacking.
The Extent of the Problem
Once you really understand the nature of the problem it may occur to you that it’s a very widespread and pervasive issue. It has always existed in Windows and will likely exist for the foreseeable future. To alter the DLL search path mechanism could have severe backward-compatibility problems for Windows and is most likely not going to happen due to the high value they have always placed in compatibility (We love you Raymond Chen!). I’ve written a program to identify all locations and filenames that a DLL could be placed to achieve persistence on a given system. The idea is that you can run this program on a clean (Gold Image) system and forensically search for any DLL name listed in the output on a machine you suspect of being compromised with this method of persistence. Similar programs may be developed to attempt to identify hijacked DLLs on a live system. I chose to write this program first however because its output helps to explain the extent of the problem. I ran the program on my laptop and it produced output which contained 1032 lines, each describing a location and filename that a DLL could be placed to be loaded at boot-time by my system. On a clean XP SP2 machine I get 91 locations listed. Here are a few lines from the output from my laptop:
Hijackable Location: C:\Program Files (x86)\iTunes\SspiCli.dll
Hijackable Location: C:\Program Files (x86)\iTunes\CRYPTBASE.dll
Hijackable Location: C:\Program Files (x86)\iTunes\CoreFoundation.dll
Hijackable Location: C:\Program Files (x86)\iTunes\MSVCR80.dll
According to this output, some program that loads when my system boots (most likely iTunes) attempts to load the DLL named “CRYPTBASE.DLL” which is commonly found in the System32 folder but an attacker could place a malicious DLL in the iTunes folder and that would be loaded instead. The program examines running processes and determines hijackable DLL locations by the following properties (applied to each loaded dll in every running process in the system):
- The process executable that loaded the DLL is not located in the System32 folder
- The DLL name is not found in the KnownDlls object
- The DLL is not found in the same directory as the executable
Any loaded DLL that contains all three properties is susceptible to being trumped by search order hijacking.
The tool (compiled and source) to identify possibly malicious 32-bit DLL locations from a clean system can be found here.
Tags: KnownDLLs, malware, persistence
DOD Cyber Crime: New Audit Viewer/Memoryze
Written by Peter Silberman
MANDIANT is going to be at DOD Cyber Crime this year. Jamie and I have both been heads down for many weeks now working on some pretty cool stuff. We are starting to come up for air and what that means for you is updates to Memoryze and Audit Viewer. We will be releasing new versions of each that coincide with DC3. I, along with many of my co-workers, will be presenting and attending. My talk abstract is very ambiguous so I thought I’d take a brief second to discuss both the talk and the changes to Audit Viewer and Memoryze.
The talk is going to be interactive. And dammit I don’t care if you don’t want to interact with me. I’m both very convincing, persistent and well…charming! You will feel compelled to join in on this talk. I promise. I know this because I’m bringing bribes… And yes, I’m bringing what you are thinking.
This talk will contain a brief intro to memory analysis, a FAQ etc. We are not going to waste much time on the nitty gritty since most people are not interested in how we chop off the last 12 bits to get a physical offset from a virtual address. I know, you just fell asleep a little. During this talk I will make a case for why memory analysis is important. I will pull from pervious APT investigations where disk analysis failed and had to be used in conjunction with memory analysis. Finally, we will discuss MANDIANT’s Malware Rating Index (MRI). We will finish with real APT incident demos where I’ll walk through the investigation of an infected system with APT.
Now, a little more about MRI. MRI is a huge update to Audit Viewer. Instead of going after a fish (malware) with a hook (signatures), I’m going after fish (malware) with a drag net (MRI). The goal of this feature is twofold. First it is going to help pinpoint specific processes that should be investigated further while attempting to eliminate some of the non-suspicious processes and get them out of the analyst’s way. It’s also designed to try and make APT detection easier. A lot of work went into looking at our samples and how they behave etc, and coming up with definable behaviors that trap those little creatures. MRI is made up of two components. The first component is a definable behavior rule set that is completely customizable. It is made up of three different types of rules:
- Process Path Verification – allows users to define what processes should be launched from what directories. This triggers on malware that copies and names itself after svchost or other system processes to subdirectories within system folders. For example a default rule is that svchost can only be executed from \windows\system32. Any time we see it running from somewhere else we flag the process.
- Process User Verification – allows users to define what processes should be running under what users. This triggers on malware spawning svchost for purposes of unmapping image bases or hiding dlls within spawned svchost. So, for example, if malware copies itself to system32\dllcache and then names itself svchost.exe, you can define a rule saying svchost.exe should be running as local service, network service, or system. When Audit Viewer see svchost running as administrator it gets flagged.
- Process Handle Inspection – this allows you to define specific rules pertaining to malware or generic behavior. For example a default rule is to flag svchost or iexplore anytime it has a process handle to cmd.exe. There is just no good reason for this to _EVER_ happen. You can also define rules based on specific malware, for example if a3c mutant is present then flag the process as being infected with sality.
All of these features are configurable from the UI by going to operations -> Configure MANDIANT MRI.
The second component of MRI is a process address space scoring mechanism. We will be releasing an update to Memoryze at DC3. The new release will contain bug fixes as well as a new feature called “Verify Digital Signatures.” When this parameter is turned on memoryze will perform a “digital signature check” on all loaded modules. This can only be enabled on live memory analysis. The digital signature check verifies the module on disk is digitally signed. We do a bunch of math and use our Least Frequency of Occurrence to trust modules that aren’t signed but occur in more than X% of processes. Where X is defined by the user. We won’t flag or catch modified binaries in memory. So if a rootkit is doing userland hooking (it should be ashamed) we won’t know about it because we are checking disk to determine if it is digitally signed. There are a lot of reasons why we can’t verify in memory digital signatures. It might make an interesting blog to detail all the reasons. With that said, this new feature gives us a good working idea of how much of the loaded modules in the process address space are signed and therefore trusted. It’s had fantastic results thus far. I’ve been using it on old incidents to see if we could have sped up results using these new methods. The answer seems to be yes in a lot of cases.
After DC3 I’ll have more blogs detailing how you can use and write better rules for MRI. But for now there will be a default distribution that you can use and modify. Again, like always, Audit Viewer is open source and free. Which means you can see the logic and rules behind MRI. Memoryze is and will stay free.
If you are going to be at DC3 and want to grab a beer I will be there from Sun (night)-Weds. Unfortunately I’m going to be missing all the great talks on Thurs so I can leave to compete in the Tough Guy Challenge. You are more than welcome to join at this race in Northern England. As I understand it there are still some open slots! See everyone at DC3!
Tags: APT, Audit Viewer, DC3, DOD Cyber Crime, malware, Malware Rating Index, MANDIANT, Memoryze, MRI
State Of Malware: Explosion of the Axis of Evil, slides etc
Written by Peter Silberman
Last week Ero Carrera and I spoke at Source Barcelona. As I mentioned previously on this blog we were both very excited to give this talk. The talk went very well! We could not have asked for a better audience. The conference itself was also a blast, and I recommend Barcelona to anyone and everyone.
We’ve gotten around to uploading the slides. They include all the statistics we came up with for this talk. When you review the slides take a look at slide 16 “Complexity of Mydoom” and slide 17 “Complexity of Kraken.” These two slides depict control flow graphs of the popular malware Craken and MyDoom. Notice how much functionality is crammed into these binaries. As an Anti Virus company that’s a lot of data and bytes to work with to generate a successful signature.
Now look at slide 44 “Sample BA”, it’s the control flow graph of an APT sample. Notice some differences? Our hope is this talk gets people thinking about the different types of threats, different malware families make to organizations, as well as the clear differences between APT and mass malware.
Tags: APT, malware, MANDIANT, source, source barcelona, virus total

