DLL planting (aka binary planting/hijacking/preloading) resurface every now and then, it is not always clear on how Microsoft will respond to the report. This blog post will try to clarify the parameters considered while triaging DLL planting issues.
It is well known that when an application loads a DLL without specifying a fully qualified path, Windows attempts to locate the DLL by searching a well-defined set of directories in an order known as DLL search order. The search order used in the default SafeDllSearchMode is as below:
- The directory from which the application loaded.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. function to get the path of this directory.
- The current directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
The default DLL search order can be changed with various options as noted in one of our previous blogpost “Load Library Safely”.
A DLL loading in an application becomes a DLL planting vulnerability if an attacker can plant the malicious DLL in any of the directories searched per the search order, and the planted DLL is not found in the prior directories searched that attacker has no access to it. For example, an application loading foo.dll that is not present in either application directory or system directory or windows directory can provide an opportunity for an attacker to plant foo.dll if he has access to the current working directory. DLL planting vulnerabilities are very convenient and is less work for an attacker, it gives very easy code execution since the DllMain() gets called immediately on loading the DLL. Attackers don’t have to worry about bypassing any mitigation if the application allows loading non-signed binaries.
Based on where the malicious DLL can be planted in the DLL search order the vulnerability broadly falls into one of the three categories:
- Application Directory (App Dir) DLL planting.
- Current Working Directory (CWD) DLL planting.
- PATH Directories DLL planting.
The above categories are what guides our response. Let’s look at these categories to see how we triage each of them.
Application Directory (App Dir) DLL planting
Application directory is where an application keeps its dependent non-system DLLs and trusts them to be intact. Files located in a program’s installation directory are presumed to be benevolent, trustworthy and a directory ACL security control is typically used to safeguard them. Anyone able to replace a binary in the installation directory, presumably has the privileges necessary to write/overwrite files. The application directory is considered a code directory, where code related artifacts for the application should be stored. If an attacker can achieve DLL overwrite within the application directory without being on the directory ACL, it’s a much bigger issue than replacing/planting a single DLL.
Let’s look at some of the scenario involved with application directory DLL planting:
Scenario 1: Malicious binary planting in a trusted application directory.
Applications installed properly generally safeguard the application directory with ACLs, elevated access (typically admin) is required to modify the content of the application directory in this scenario. For example, Microsoft Word’s installation location is “C:\Program Files (x86)\Microsoft Office\root\Office16\”. An admin access is required to modify anything in this directory. A victim, who has admin rights, can be tricked/socially engineered to plant DLLs in a trusted location but if such is the case, they can be tricked/social engineered to do worse things.
Scenario 2: Malicious binary planted in an untrusted application directory.
Application installed via XCOPY without installer being used, available on a share, downloaded from internet, standalone executable in a non ACLed directory are some of the scenarios that falls under untrusted category. For example, an installer (including redistributable, setup.exe generated by ClickOnce, and self-extracting archives generated by IExpress) downloaded from internet and running from default “Downloads” folder. Launching an application from an untrustworthy location is dangerous, a victim can be easily tricked/fooled to plant DLLs into these untrusted locations.
A DLL planting issue that falls into this category, Application Directory DLL planting, is treated as Defense-in-Depth issue that will be considered for updates in future versions only. We resolve any MSRC case that fall in this category as vNext consideration, mainly due to the amount of social engineering involved in the attack and the by design nature of the bug. A victim would have to be tricked into placing the malicious DLL (malware) where it can be triggered AND perform a non-recommended action (like running an installer in the same directory as the malware). A non-installed application has no reference point for “known good directory/binaries”, unless it creates the directory itself. Ideally, the installer should create a temporary directory with a randomized name (to prevent further DLL planting), extract its binaries to it and use them to install the application. While an attacker can make use of a drive-by download to place the malware on the victim’s system, such as into the “Downloads” folder, the essence of the attack is social engineering.
In Windows 10 Creators Update we added a new process mitigation that can be used to mitigate the Application Directory DLL planting vulnerabilities. This new process mitigation, PreferSystem32, when opted in toggles the order of application directory and system32 in the DLL search order. Because of this any malicious system binary can’t be hijacked by planting it in the application directory. This can be enabled for the scenarios where the process creation can be controlled.
Current Working Directory (CWD) DLL planting
Applications typically set the directory from where they are invoked as the CWD, this applies even when the application is invoked based on the default file association. For example, clicking a file from the share “D:\temp\file.abc”’ will make “D:\temp” as the CWD for the application associated with the file type .abc.
The scenario of hosting files in a remote share, especially a webdav share, makes CWD DLL planting issues more vulnerable. This way an attacker can host the malicious DLL along with the file and social engineer the victim to open/click the file to get the malicious DLL loaded into the target application.
Scenario 3: Malicious binary planted in the CWD.
Application loading a DLL not present in any of the first three trusted location will look for the same in the untrusted CWD. Victim opening a .doc file from the location \\server1\share2\ will launch Microsoft Word, if the Microsoft Word can’t find one of its dependent DLL oart.dll in the trusted location it will try to load it from the CWD \\server1\share2\. Since the share is an untrusted location attacker can easily plant oart.dll to feed into the application.
Trigger => \\server1\share2\openme.doc
Application => C:\Program Files (x86)\Microsoft Office\root\Office16\Winword.exe
App Dir=> C:\Program Files (x86)\Microsoft Office\root\Office16\
CWD => \\server1\share2\
Malicious DLL => \\server1\share2\OART.DLL
A DLL planting issue that falls into this category of CWD DLL planting is treated as an Important severity issue and we will issue a security patch for this. Most of the DLL planting issue that we have fixed in the past falls into this category, the advisory 2269637 lists a subset of them. This brings to a question why any Microsoft applications would load DLLs that are not present in its application directory or System directory or Windows directory. It so happens that there are various optional components, different OS editions and multiple architectures that come with different set of binaries that sometimes applications fail to consider or verify effectively before loading the DLLs.
PATH Directories DLL planting
The last resort to find the DLLs in the DLL search order is the PATH directories, which is a set of directories that has been added by various applications to facilitate user experience in locating the application and its artifacts.
The directories that are in the PATH environment variable are always admin ACLed and a normal user can’t modify contents of these directories. If we have a world writable directory exposed via PATH, then it is a bigger issue than just the single instance of DLL planting and we deal with that as an important severity issue. But just the DLL planting issue is considered as a low security issue since we don’t expect to cross any security boundary with this planting vulnerability. Thus, DLL planting issues that fall into the category of PATH directories DLL planting are treated as won’t fix.
We hope this clears up questions on how we triage a reported DLL planting issue and what situations we consider to be severe enough to issue a security patch. Below is a quick guide to what we fix/won’t fix via a security release (down level).
What Microsoft will address with a security fix
CWD scenarios – Like an associated application loading a DLL from the untrusted CWD.
What Microsoft will consider addressing the next time a product is released
Application directory scenarios – This is at complete discern of product group based on whether it is an explicit load or implicit load. Explicit load can be tweaked but the implicit loads (dependent DLLs) are strictly by-design as the path can’t be controlled.
What Microsoft won’t address (not a vulnerability)
PATH directory scenarios – Since there can’t be a non-admin directory in the PATH this can’t be exploited.