by Nilaa Maharjan, Security Research
Click the links and navigate to each section:
Due to the abundance of components in an operating system, attackers with local access have an extensive range of possible attack vectors, even if they have insufficient privileges. Security analysts need to mount a huge effort to watch for unusual behavior and detect attacks.
There’s a trend of adversaries using unsigned DLLs, DLL search order hijacking, and exploiting many vulnerabilities using similar methods. With the increase of DLL attacks (T1574) in mind, we evaluated the detection capabilities of our SIEM+SOAR solution as part of our routine hunting activities.
Before we get started on how to detect and respond to malicious DLLs, let’s start by defining DLLs and how adversaries are using them.
Summary: Dynamically Linked Libraries (DLL). Analysts need to mount a huge effort to detect and watch for unusual behavior. Adversaries are using unsigned DLLs and attacks are on the increase and are stealthy in their methods. There are three types of DLL: DLLs mostly written to an unprivileged path, DLLs that are unsigned, DLLs that are loaded by a signed process. Programs in Microsoft Windows can specify which libraries are loaded at runtime.
The good news is you can investigate and respond to these attacks with Logpoint head here.
What are DLLs?
Let’s start with Windows Internals. Dynamically Linked Libraries (DLL) provide a large portion of the functionality of the Windows operating system. The purpose of using shared libraries, or DLLs, according to Microsoft, is to facilitate code reuse, modularization, and faster loading of libraries shared by different applications. If a binary needs to use one of the functions of a DLL, it can load it into memory and inherit the ability to execute that function. In practice, DLLs typically provide an export table with a list of functions that executables can import.
There are two main ways to achieve the function list:
- At link time – When the program is compiled, an import table is written into the headers of the Portable Executable (PE). To put it simply, it keeps track of which function needs to be imported from which DLL. Therefore, whenever the program is executed, the linker knows what to do and loads all the required libraries transparently on your behalf.
- At runtime – Sometimes, you need to import a library at runtime. At this point, the linker has already done its part of the job, so if you want to do so you’ll have to take care of a few things yourself. In particular, you can call LoadLibrary() or LoadLibraryEx() from the Windows API.
When a binary loads a DLL, it must know where it’s located on the disk, but it can do so in a variety of ways, such as to reference the DLL’s name within the executing binary, which causes the operating system to enumerate through several locations in a preset order to discover and load any DLL by that name.
DLLs are a persistent attack vector
To remedy the fact that DLLs are a persistent attack vector, their basic design would need to change. In recent years, Windows has adopted a new model to ensure that loaded libraries are validated, such as signing, manifest checks, and other measures. However, there are still many DLLs on the system that are not covered by the new security procedures. Furthermore, third-party developers do not carry out these tests in a systematic manner.
When a Windows program is compiled, static libraries are either included or loaded at run time. The majority of the system’s DLLs are located in C:Windows\System32 or C:Windows\SysWow64, while third-party software is located in local folders such as Program Files.
Based on our research and observations, there are three types of malicious DLLs.
- DLLs mostly written to an unprivileged path.
- DLLs that are unsigned.
- DLLs that are loaded by a signed process, whether by a utility dedicated to loading DLLs (such as exe) or an executable that loads DLLs as part of its activity. Evading detection.
However, they can all be grouped into a method we refer to as a DLL misuse attack.
What is a DLL misuse attack?
Programs in Microsoft Windows can specify which libraries are loaded at runtime by supplying a full path or by using another mechanism, such as a manifest. A program manifest is an external file or embedded resource within an application that manages the names and versions of shared side-by-side assemblies that should be loaded when executed. DLL redirections, filenames, and full paths can all be found in a program manifest. So, merely referring to a library filename is considered a weak reference and is vulnerable to DLL side-loading.
When a weak reference to a library is established, Windows attempts to locate the DLL using a pre-defined search order. The directory from which the application is loaded is the first location where Windows will look. Exploiting this known condition, a DLL side-loading attack is an adversarial approach that seeks to exploit weak library references and the usual Windows search order by putting a malicious DLL file on a system that masquerades as a legal DLL and is automatically loaded by a legitimate program.
For more information regarding DLL side-loading, reference MITRE ATT&CK Technique T1574.002.
An adversary with sufficient development skills can create a malicious DLL that shares its name and exported functions with a valid one but carries a malicious payload. The attacker can then install the malicious DLL in a suitable directory and instruct the executing binary to load the custom DLL payload. An opponent, for example, could transfer a genuine system binary to an odd directory and then insert a malicious DLL with the same name as a legitimate one in the same directory. When the relocated binary searches for the normal DLL, it first finds and runs the malicious one in the same directory.
We rarely see adversaries overwrite existing DLLs on disk. One of the primary reasons is that it may cause the endpoint to become unstable, resulting in the detection of the malicious DLL, disconnection of the host, and the adversary losing their footing. Adversaries write system binaries somewhere else on the disk along with a malicious DLL in the same directory as the system binary, it’s loaded into memory when the relocated binary executes, rather than overwriting the legitimate DLL visibly.
For more information regarding DLL search order hijacking, reference MITRE ATT&CK Technique T1574.001.
DLL hijacking is a stealthy, persistent attack
DLL hijacking is an extremely effective method of launching malicious code that attackers have long used. When you run a Windows application, it loads libraries from the local directory first, then from the system directories. As a result, if an adversary updates one of the application’s legitimate DLLs, the malicious DLL will be loaded by the application. Because the malicious code is executed every time the program is launched, the approach enables the persistence and execution of any arbitrary code.
The attack is stealthy because it doesn’t use any additional binaries and the code runs in memory. As a result, the opponent gets numerous advantages: They leave no easily detectable traces. No process, no autorun keys, no registry update, no scheduled task, and no service. If the binary that loads the DLL is allowed over the firewall, hijacking can bypass firewall regulations. It eliminates the need for loud approaches like process injection. In addition, there are also tools to automate the process of attack, as well as complex attacks that contain the code of the genuine DLL, within the fake one, to keep the application from crashing.
An overview of the DLL misuse threat landscape
The search order hijacking vulnerability in Windows has existed since Windows XP, therefore DLL side-loading is not a novel technique. Due to its nature and ease, the use of DLL is increasingly being used by ransomware operators to execute a ransomware payload to avoid detection by protection products.
An analysis by Unit42, between February and August 2022, shows that most malware families used some sort of unsigned DLLs. The following table is based on two XQL queries, one checking for unsigned DLLs being loaded by rundll32.exe/regsvr32.exe and the other for signed software loading unsigned DLLs.
Malware families using unsigned DLLs. Source: Unit42
The data concluded that the preferred execution technique to load a malicious DLL by banking trojans and individual threat actors is rundll32.exe or regsvr32.exe, while APT groups used the DLL side-loading technique most of the time.
You may only observe the process executing from an obscure directory depending on the level of visibility into your environment. For proper detection and analysis, Logpoint recommends setting up Sysmon and manually adding relevant rules or using a Logpoint-provided configuration file for easier detection and simpler use.
Why it matters
Since DLLs are baked into Windows operations, there are plenty of threat actors and threats that use it as an initial vector, pivot point, or to get a foothold on the system. Some of them include:
- APT41: uses search order hijacking
- Astaroth: uses search order hijacking to launch itself
- BOOSTWRITE: exploits loading of legitimate .dll file
- BackdoorDipolomacy: uses search order hijacking
- Chaes: search order hijacking to load malicious DLL payloads
- Crutch: persists a search order hijacking through search engines
- Downdelph: escalates privileges through search order hijacking of .exe files
- FinFisher: variants use DLL search order hijacking
- HTTPBrowser: interferes with DLL load order
- HinKit: search order hijacking a persistence mechanism
- InvisiMole: search order hijacking launched infected DLL during startup
- Melcoz: uses DLL hijacking to bypass security controls
- RTM: search order hijacking to interfere with TeamViewer
- Ramsey: hijacks outdated Windows applications
- ThreatGroup-3390: uses DLL search order hijacking to distribute a payload
- Tonto team: interferes with legitimate Microsoft executable to load malicious DLL
- Whitefly: search order hijacking to infect malicious DLL
- menuPass: uses DLL search order hijacking
The large number of attackers using DLL means they are exploiting a lot of surfaces and employing various techniques.
Investigating DLL hijacking using Logpoint
Occurrences of threat actors or malware overwriting existing binaries or modules on a system to carry out a DLL side-loading attack are rare. Doing so can lead to a heightened risk of system crashes or problems that lead to detection.
To detect an attack, it’s crucial to think like a hacker. One trick used by attackers is to “hide in plain sight” and use process names which are very common in Windows. There are two trains of thought to consider when trying to detect hijacking.
- Approach 1: List all (system32) binaries that are normally signed. Cross-check against process executions that have the same filename, but are unsigned.
- Approach 2: Make a list of the top 100 executed (system) processes. Obtain all unique hashes for those processes and filter all unique processes with a low prevalence and check if they’re signed. This is based on the assumption that most commonly used files are usually signed, though, this assumption doesn’t always hold, unfortunately, but the query does help in identifying suspicious unsigned files on your system.
There are ways to improve both approaches. One of the most significant improvements required is to validate if the certificate is signed by the expected issuer.
We created an alert that detects the loading of a non-Microsoft signed DLL that is either missing from a standard Windows installation (phantom DLL) or that can be loaded from a different place by a native Windows process.
Phantom DLL loaded for persistence or privilege escalation
file IN [wlbsctrl.dll",
"wbemcomn.dll", "WptsExtensions.dll", "Tsmsisrv.dll", "TSVIPSrv.dll",
"WindowsCoreDeviceInfo.dll", "Ualapi.dll", "wlanhlp.dll",
"phoneinfo.dll", "EdgeGdi.dll", "cdpsgshims.dll",
Even when the binary may be signed, its execution would still be considered an anomaly within a program execution dataset. High scrutiny here is important to catch developing threats as the use of DLL hijacking is often used to escalate privileges. Given that the system is vulnerable, an attacker will create or overwrite a DLL with basic privileges and try to execute it with a process that has high privileges. The detection at this point is to collect and analyze DLLs loaded by high-privilege processes for their paths against FileCreate/FileModify events.
Needless to say, there are legitimate processes that will generate these types of logs and events. Any FileCreate/FileModify done by “NT Authority\System” and the “RID 500″ can be generally ignored. The focus should remain on processes with default or limited token elevation as fully elevated tokens usually mean the user has admin privileges already.
A tool by SANS can be used to detect whether a DLL has been hijacked, which might assist in manual hunting, but as the article suggests – DLL hijacking isn’t always malicious. There are many digitally signed libraries that sit in the base directory of an application.
A similar tool, Process Monitor by Microsoft can also be useful for analysts trying their hand at manual detection. This tool enables developers and administrators to closely track the behavior of a running process.
If a vulnerable path is being hit, you will see something that is similar to the following: The call to the remote file share to load a DLL indicates that this is a vulnerable program.
Four golden rules when hunting DLLs
- For DLL side-loading, we recommend paying attention to known third-party software placed in non-standard directories.
- Focus on the file’s entropy – binaries that have a high value of entropy may contain a packed section that will be extracted during execution.
- Focus on the frequency of execution – high-frequency results may indicate a legitimate activity that occurs periodically, while low-frequency results may be a lead for an investigation.
- Focus on the file’s path – results that contain folders or files with scrambled names are more suspicious than others.
The below queries can help hunt for DLLs:
DLL side loading via Microsoft Defender
"process" IN ["*\MpCmdRun.exe","*\NisSrv.exe"]
-"process" IN ["C:\Program Files\Windows Defender\*","'C:\ProgramData\Microsoft\Windows Defender\Platform\*"] image="*\mpclient.dll"
Xwizard DLL side loading detected
Wmiprvse spawning process
norm_id=WinServer* (event_id=4688 OR event_id=1)
("process"="*WmiPrvSe.exe" OR parent_image="*WmiPrvSe.exe")
-target_logon_id="0x3e7" -logon_id="0x3e7" -user IN EXCLUDED_USERS
WMI modules loaded
image IN ["*wmiclnt.dll", "*WmiApRpl.dll", "*wmiprov.dll", "*wmiutils.dll", "*wbemcomn.dll", "*wbemprox.dll", "*WMINet_Utils.dll", "*wbemsvc.dll", "*fastprox.dll"]
-source_image IN ["*WmiPrvSe.exe", "*WmiAPsrv.exe", "*svchost.exe","*DeviceCensus.exe", "*CompatTelRunner.exe", "*sdiagnhost.exe", "*SIHClient.exe", "*ngentask.exe", "*taskhostw.exe", "*MoUsoCoreWorker.exe", "*WMIADAP.exe", "*Sysmon.exe", "*unsecapp.exe", "*logman.exe", "*systeminfo.exe", "*nvcontainer.exe", "*WMIC.exe", "*explorer.exe", "*opera_autoupdate.exe", "*MsMpEng.exe", "*thor64.exe", "*thor.exe"]
-image IN ["*Program Files\*", "*Program Files (x86)\*]
-user IN EXCLUDED_USERS
FoggyWeb backdoor DLL loading
Svchost DLL search order hijack
file IN ['*tsmsisrv.dll', '*tsvipsrv.dll', '*wlbsctrl.dll']
Fax service DLL search order hijack
-(image IN "*\Windows\WinSxS\*")
How to leverage response with Logpoint SOAR
Logpoint SOAR makes it easy for analysts to streamline defenses. Playbooks provide operational procedures for planning and conducting cybersecurity incident and vulnerability response activities and detail each step for both incident and vulnerability detection.
Based on the organization’s policy and the incident response team procedures, an investigation playbook will collect as much data as possible and generate a report.
Logpoint SOAR has out-of-the-box playbooks for suspicious process investigation
If and when an active attack has been detected, an organization should always follow the already set IT and security guidelines. Plenty of resources are available to create and follow. Some notable ones are provided by CISA, FBI, and frameworks by NIST.
However, using Logpoint, analysts can take the following actions for immediate responses to the attacks.
- Blocking IoCs: Logpoint’s updated IoC lists with hashes, domains, and IPs, can be turned on as alerts and used to block as soon as they are detected in the network.
- Isolate the endpoints: When an attack is detected or a system is compromised, the immediate action should be to isolate the system, take proper logs, evaluate the situation and remediate.
- Deleting malicious files: When an attack vector using a malicious file matches one of our alerts, playbooks can be run to immediately quarantine the machine, remove it from the network and delete the file in question.
These actions come out of the box as part of Logpoint playbooks.
Along with the given playbooks, organizations detecting potential APT activity in their IT or OT networks should:
- Secure backups. Ensure your backup data is offline and secure. If possible, scan your backup data with an antivirus program to ensure it is free of malware.
- Collect and review relevant logs, data, and artifacts.
- Consider soliciting support from a third-party IT organization to provide subject-matter expertise, ensure the actor is eradicated from the network, and avoid residual issues that could enable follow-on exploitation.
Note: The provided playbooks are a generic version and will not work without adapting according to your environment. Contact Logpoint for tailor-made playbooks and queries.
Upon detecting traces of exploitation, analysts should not spend crucial time trying to execute a pre-defined remediation plan. This is where Logpoint SOAR comes to the rescue. Detecting exploitation is simple and seamless because Logpoint is a unified SIEM+SOAR solution that uses an alert (SIEM event) to automatically trigger a SOAR playbook.
Disable Active Directory user
When the trigger, in this case, an unsigned DLL is running other services, the playbook removes the user from Active Directory and changes the user’s password using a random password generator.
Disabling an Active Directory user playbook
Case view of disabling Active Directory user
Delete malicious files with Logpoint AgentX
Logpoint is excited to release a new capability as part of our Converged SIEM platform: Logpoint AgentX, a built-in response capability on endpoints. With the addition of Logpoint AgentX, users can run a playbook and any malicious file is simply deleted with the Remove Item playbook. Logpoint AgentX is available now: Contact your representative.
Logpoint AgentX Remove Item playbook
Logpoint AgentX Remove Item query status
Logpoint AgentX Remove Item timeline
A converged security operations platform gives analysts an edge
The majority of detection methods for malicious DLLs rely on the module’s behavior after it has been loaded into memory. This may reduce the capacity to detect and prevent all harmful modules. Even with near real-time detection, there are extremely few ways to identify and stop DLL hijacking before it causes major harm.
Having said that, you can proactively seek malicious unsigned DLLs using methods like those described above.
Knowing your network’s baseline in terms of legitimate software or behavior might limit the number of results provided by the queries, allowing you to focus on potentially suspect results. But as we have discussed, DLL hijacking is a difficult process to detect and stop in its tracks, but a good endpoint response capability combined with SIEM+SOAR gives analysts an edge.