It's those darned DLLs again...

There's been a lot (and I mean a LOT) of traffic on the interwebs lately regarding a vulnerability associated with how DLLs are loaded on Windows systems. In short, the idea is that due to how applications look for DLLs that aren't explicitly defined by their path, and how the current working directory can be defined (includes how an application is launched), the application can end up loading a malicious DLL that is in a non-traditional directory.

First, some background/references:
DLL Search Order Vuln (circa 2000)
MSDN DLL Search Order article
ACROS Security's recent announcement
Recent Mandiant blog post (author: Nick Harbour)
SANS ISC blog post (author: Bojan Zdrnja)
ComputerWorld article
Register article (UK)
Rapid7 blog post (author: HD Moore)
Metasploit blog post (author: HD Moore)
SecDev blog post (author: Thierry Zoller)
MS Research and Defense blog
MS Security Advisory 2269637
MS KB Article 2264107 (includes a Registry change)

This was originally something that was pointed out 10 years ago...the new twist is that it has been found to work on remote resources. MS has issued instructions and guidance on how to properly use the appropriate APIs to ensure the safe loading of libraries/DLLs. However, this, combined with the findings from ACROS and others (see the paper referenced in HD's Rapid7 blog post), pretty much tells us that we have a problem, Houston.

The DLL search order vulnerability is a class of vulnerability that can be implemented/exploited through several avenues. Basically, some mechanism needs to tell an application that it needs to load a DLL (import table, Registry entry, etc.) through an implicit (i.e., not explicitly defined) path. The application will then start looking for the DLL in the current working directory...depending on how this exploit is implemented, this may be the directory where the application resides, or it may be a remote folder accessible via SMB or WebDAV. Therefore, the application starts looking for the DLL, and as there is no validation, the first DLL with the specified name is loaded. One thing to keep in mind is that the DLL cannot break required functionality needed by the application, or else the application itself may cease to work properly.

Okay, so what does all of this mean to forensic analysts? So some user clicks on a link that they aren't supposed to and accesses a specific file, and at the same time a malicious DLL gets loaded, and the system becomes infected. Most often, forensic analysts end up addressing the aftermath of that initial infection, finding indications of secondary or perhaps tertiary downloads. But what question do customers and regulatory bodies all ask?

How was the system originally infected?

What they're asking us to do is, to do a root cause analysis and determine the initial infection vector (IIV).

Some folks may feel that the method by which the DLL is designated to load (import table, file extension association, etc.) is irrelevant and inconsequential, and when it comes to a successful exploit, they'd be right. However, when attempting to determine the root cause, it's very important. Take Nick's post on the Mandiant blog, for example...we (me, and the team I work with) had seen this same issue, where Explorer.exe loaded ntshrui.dll, but not the one in the C:\Windows\system32 directory. Rather, the timeline I put together for the system showed the user logging in and several DLLs being loaded from the system32 directory, then C:\Windows\ntshrui.dll was loaded. The question then became, why was Explorer.exe loading this DLL? It turned out that when Explorer.exe loads, it checks the Registry for approved shell extensions, and then starts loading those DLLs. A good number of these approved shell extensions are listed in the Registry with explicit paths, pointing directly to the DLL (in most cases, in the system32 directory). However, for some reason, some of the DLLs are listed with implicit paths...just the name of the DLL is provided and Explorer.exe is left to its own devices to go find that DLL. Ntshrui.dll is one such DLL, and it turns out that in a domain environment, that particular DLL provides functionality to the shell that most folks aren't likely to miss; therefore, there are no overt changes to the Explorer shell that a user would report on.

Yes, I have written a plugin that parses the Registry for approved shell extensions. It's not something that runs quickly, because the process requires that the GUIDs that are listed as the approved shell extensions then be mapped to the CLSID entries...but it works great. This isn't as nifty as the tools that Nick and HD mention in their blog posts, but it's another avenue to look to...list all of the approved shell extensions listed with implicit paths, and then see if any of those DLLs are resident in the C:\Windows directory.

Again, there's a lot of great information out there and a lot to digest with respect to this issue, but the overarching issue that I'm most interested in now is, what does this mean to a forensic analyst, and how can we incorporate a thorough examination for this issue into our processes? Things that forensic analysts would want to look for during an exam would be the MRU lists for various applications...were any files recently accessed or opened from remote resources (thumb drives, remote folders, etc.)? If there's a memory dump available (or the output of handles.exe or listdlls.exe) check to see if there are any DLLs loaded by an application that have unusual paths.

Some of the issues you're going to run into is that you may not have access to the remote resource, and while you may see indications of a file being accessed, you won't have any direct indication that a DLL was in the same folder. Or, if the vulnerability was exploited using a local resource, AV applications most likely are not going to flag on the malicious DLL. In some cases, a timeline may provide you with a sequence of events...user launched an application, remote file was accessed, system became infected...but won't show you explicitly that the malicious DLL was loaded. This is why it is so important for forensic analysts and incident responders to be aware of the mechanisms that can cause an application to load a DLL.

One final note...if you're reading MS KB article 2264107, you'll see that at one point, "CWDIllegalInDllSearch" is referred to as a Registry key, then later as a value. Apparently, it's a value. Kind of important, guys. I'm just sayin'...

I've written a plugin that checks for the mentioned value, and updated another plugin that already checks the Image File Execution Options keys for Debugger values to include checking for this new value, as well.