<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Purple Labs]]></title><description><![CDATA[Purple Labs]]></description><link>https://purplelabs.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 25 Oct 2026 20:08:10 GMT</lastBuildDate><atom:link href="https://purplelabs.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[DLL Search Order Abuse: 
Privilege Escalation, and EDR Unhooking]]></title><description><![CDATA[A deep technical breakdown of Windows DLL Search Order abuse, explaining how attackers achieve code execution and privilege escalation, along with…]]></description><link>https://purplelabs.hashnode.dev/dll-search-order-abuse-privilege-escalation-and-edr-unhooking</link><guid isPermaLink="true">https://purplelabs.hashnode.dev/dll-search-order-abuse-privilege-escalation-and-edr-unhooking</guid><category><![CDATA[Malware Research]]></category><category><![CDATA[windows security]]></category><category><![CDATA[Privilege Escalation]]></category><category><![CDATA[dll hijacking]]></category><category><![CDATA[red team]]></category><category><![CDATA[blueteam]]></category><category><![CDATA[detection engineering ]]></category><category><![CDATA[EDR]]></category><category><![CDATA[cybersecurity]]></category><dc:creator><![CDATA[Sravan]]></dc:creator><pubDate>Wed, 18 Feb 2026 12:49:40 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-introduction"><strong><mark>Introduction</mark></strong></h2>
<p>Modern enterprise environments rely heavily on third-party and internally developed applications to support daily operations. These applications frequently depend on Dynamic Link Libraries (DLLs) to load required functionality at runtime.</p>
<p>While DLL-based modular design improves efficiency and maintainability, improper configuration of DLL loading mechanisms can introduce security risks. Specifically, weaknesses in the Windows DLL search order may allow unintended or malicious DLLs to be loaded if directory permissions are misconfigured.</p>
<p>When this occurs, attacker-controlled code can execute within the context of a legitimate process. Depending on the privilege level of the target application, this may lead to:</p>
<ul>
<li><p>Unauthorized code execution</p>
</li>
<li><p>Privilege escalation</p>
</li>
<li><p>Persistence opportunities</p>
</li>
<li><p>EDR interaction or behavioral manipulation</p>
</li>
</ul>
<p>This article provides a technical deep dive into Windows DLL loading internals, explains how search order abuse works, presents controlled lab observations, and discusses defensive detection strategies.</p>
<h2 id="heading-what-is-a-dll"><strong><mark>What is a DLL?</mark></strong></h2>
<p>A DLL (Dynamic Link Library) is a file that contains reusable code and functionality that can be shared across multiple programs. Instead of embedding all functionality inside a single executable (EXE), Windows applications load required DLLs at runtime. This modular design reduces redundancy, improves memory efficiency, and simplifies maintenance. Windows itself relies heavily on DLLs to provide shared system functionality. Without DLLs, each application would need to include duplicate copies of common code, resulting in significant resource waste and increased system overhead.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771413868134/2e47e5de-c666-4665-acbc-c0ef442bf5c4.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-how-windows-loads-a-dll"><strong><mark>How Windows Loads a DLL?</mark></strong></h3>
<p>When a program starts and requires a DLL, Windows does not randomly load it. The Windows loader follows a predefined search order to locate the required library.</p>
<p>If the DLL is not found in one location, Windows continues searching through the next location in the sequence.</p>
<p>Understanding this order is essential when analyzing DLL search order abuse scenarios.</p>
<p>Default DLL Search Order (Standard Behavior)</p>
<p>In a typical configuration (Safe DLL Search Mode enabled, which is default in modern Windows versions), Windows searches in the following order:</p>
<ol>
<li><p><strong>Directory of the executable (Application directory)</strong><br /> Windows always checks the folder containing the executable first.</p>
</li>
<li><p><strong>C:\Windows\System32</strong></p>
</li>
<li><p><strong>C:\Windows\System</strong></p>
</li>
<li><p><strong>C:\Windows</strong></p>
</li>
<li><p><strong>Current Working Directory (CWD)</strong></p>
</li>
<li><p><strong>Directories listed in the PATH environment variable</strong></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771417347191/2ac5aeed-b108-4d04-9560-b9ca35dd408e.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-dll-internals"><strong><mark>DLL Internals</mark></strong></h2>
<p>A DLL (Dynamic Link Library) is not merely a passive file containing reusable code. When loaded into a process, Windows maps the DLL into memory and may execute code inside it as part of the initialization sequence. Understanding this execution behavior is critical when analyzing DLL hijacking scenarios.</p>
<p>What Does "Loading a DLL" Actually Mean?</p>
<p>When a DLL is loaded:</p>
<ol>
<li><p>The operating system maps the DLL into the process’s virtual memory.</p>
</li>
<li><p>The loader resolves imported functions.</p>
</li>
<li><p>Relocations are applied if necessary.</p>
</li>
<li><p>The entry point function <code>DllMain()</code> is executed automatically.</p>
</li>
</ol>
<p>It is important to note that Windows does <strong>not</strong> simply read the file — it executes code inside the DLL during the loading phase.</p>
<p>The DllMain Function</p>
<p>Every standard DLL contains an entry point called DllMain:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771412960656/72ccc2f2-b29f-4546-81ff-0dbad76676ee.png" alt class="image--center mx-auto" /></p>
<p>Understanding the Four DllMain Cases</p>
<p>Every standard Windows DLL contains an entry point function called <code>DllMain</code>. This function is automatically invoked by the Windows loader when specific events occur within the process lifecycle.</p>
<p>The <code>fdwReason</code> parameter determines why the function is being called.</p>
<p><code>DLL_PROCESS_ATTACH</code> Triggered when the DLL is loaded into a process. This is the most security-relevant case because any code inside this block executes immediately when the DLL is mapped into memory.</p>
<p><code>DLL_THREAD_ATTACH</code> Triggered whenever a new thread is created within the process.</p>
<p><code>DLL_THREAD_DETACH</code>Triggered when a thread exits cleanly.</p>
<p><code>DLL_PROCESS_DETACH</code> Triggered when the DLL is unloaded or when the hosting process exits.</p>
<p>Security Perspective : From an offensive and defensive standpoint, <code>DLL_PROCESS_ATTACH</code> is the most significant case. If a malicious DLL is loaded due to search order abuse, code inside this block executes automatically within the context and privilege level of the target process.</p>
<p><em>If the target process runs as SYSTEM or Administrator, the DLL inherits those privileges.</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771413645420/ca39dd12-f28a-423e-8f88-26678a1cf85e.png" alt class="image--center mx-auto" /></p>
<p>DllMain and the Process Lifecycle</p>
<p>The four DllMain notifications directly correspond to the Windows process and thread lifecycle. In simple terms, Windows informs the DLL about lifecycle events so that it can execute appropriate initialization or cleanup logic.</p>
<p>A DLL often contains code that must run when:</p>
<ul>
<li><p>A process starts</p>
</li>
<li><p>A thread is created</p>
</li>
<li><p>A thread exits</p>
</li>
<li><p>A process terminates</p>
</li>
</ul>
<p>Windows communicates these lifecycle events by invoking <code>DllMain</code> with one of the four predefined reasons.</p>
<p>What Is the Process Lifecycle?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771414416459/7b0a8f26-28e2-4dcc-8a68-d77a6379cb0a.png" alt class="image--center mx-auto" /></p>
<p>A process lifecycle represents the lifetime of a program from creation to termination.</p>
<p>It typically includes:</p>
<ul>
<li><p>Process creation</p>
</li>
<li><p>Thread initialization</p>
</li>
<li><p>Virtual memory allocation</p>
</li>
<li><p>Security token assignment</p>
</li>
<li><p>Thread termination</p>
</li>
<li><p>Process termination</p>
</li>
<li><p>Resource cleanup on exit</p>
</li>
</ul>
<p>Windows monitors both process and thread states internally. When specific lifecycle events occur, the Windows loader calls <code>DllMain</code> with the corresponding notification.</p>
<p>If the DLL implements logic for that notification, the code executes within the context and privilege level of the hosting process.</p>
<h3 id="heading-controlled-lab-simulation"><mark>Controlled Lab Simulation</mark></h3>
<p>To understand the security implications of DLL search order abuse, a controlled lab environment was configured. The goal was to observe how a manipulated DLL could influence process behavior when placed in a writable directory within the DLL search path.</p>
<h3 id="heading-step-1-application-enumeration">Step 1 – Application Enumeration</h3>
<p>Installed third-party applications were enumerated to identify potential targets. Registry inspection was used to list installed software and associated uninstall paths.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771414966603/cbc9211a-016a-4fec-bee6-9debd64edaca.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-privileged-service-identification">Step 2 – Privileged Service Identification</h3>
<p>Applications running with elevated privileges were analyzed, as these present higher security impact if compromised.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771415020541/ea2fb987-c500-42f3-891c-c2bdbdd552a6.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-directory-permission-assessment-and-missing-dll-discovery">Step 3 – Directory Permission Assessment and Missing DLL Discovery</h3>
<p>To determine whether DLL hijacking conditions were present, directory permissions of the target application were evaluated. Writable application directories can introduce risk if the application loads DLLs from those locations during startup.</p>
<p>To identify potential missing or unresolved DLL dependencies, Process Monitor (Procmon) was used in a controlled lab environment.</p>
<p>Using Procmon to Identify Missing DLLs</p>
<p>Procmon was configured to:</p>
<ul>
<li><p>Monitor the target process during execution</p>
</li>
<li><p>Filter events specific to the application binary</p>
</li>
<li><p>Identify file system operations returning <code>NAME NOT FOUND</code></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771415354788/a735cb87-c57b-4dab-b66d-88f270d85f48.png" alt class="image--center mx-auto" /></p>
<p>By filtering for file load attempts that resulted in <code>NAME NOT FOUND</code>, it was possible to observe whether the application attempted to load DLLs that were not present in its directory structure.</p>
<p>If the application attempts to load a DLL from a writable directory and that DLL does not exist, this may indicate a potential search order weakness.</p>
<p>If an attacker can place a malicious DLL in a higher-priority location within that search order, the malicious DLL may be loaded instead of the legitimate one.</p>
<h3 id="heading-step-4-controlled-testing-dll-development">Step 4 – Controlled Testing DLL Development</h3>
<p>A test DLL was Developed and introduced into a writable location within the DLL search path to observe loader behavior.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771415727313/9afb3926-cbbd-43cc-b043-782b3d1c0ea6.png" alt class="image--center mx-auto" /></p>
<p>Stage-1 code:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771416156218/38d34041-5bef-48ce-84bc-8025873457d4.png" alt class="image--center mx-auto" /></p>
<p>It will attempt to manipulate EDR DLL “edrpm64.dll” (Open source EDR), unhook the opensource EDR.</p>
<p>Stage-2 code:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771416319416/e949732b-6886-4cfe-881f-a5e14ab5625a.png" alt class="image--center mx-auto" /></p>
<p>If the host process runs with elevated privileges, the DLL logic executes with the same privileges and creates a reverse shell.</p>
<h3 id="heading-step-4-transfer-the-dll-file-to-target-machine-and-place-it-in-the-required-folder-when-application-launched-malicious-code-gets-executed">Step 4 – Transfer the dll file to Target machine and place it in the required folder, when application launched, malicious code gets executed.</h3>
<h3 id="heading-the-test-confirmed-that-when-a-dll-is-loaded-into-a-privileged-process-its-code-executes-with-the-same-elevated-privileges-and-gains-the-shell"><strong><mark>The test confirmed that when a DLL is loaded into a privileged process, its code executes with the same elevated privileges, and gains the shell.</mark></strong></h3>
<h1 id="heading-detection-amp-defensive-strategies"><strong>Detection &amp; Defensive Strategies</strong></h1>
<p>After demonstrating how DLL Search Order Abuse works, it is critical to understand how defenders can detect and prevent this technique.</p>
<p>DLL hijacking leaves observable telemetry in Windows logs and EDR systems. By monitoring module loads, file creation events, and privilege context, defenders can identify suspicious behavior.</p>
<p><mark>Behavioral Indicators</mark> of DLL Search Order Abuse</p>
<p>DLL search order abuse often includes one or more of the following indicators:</p>
<ul>
<li><p>A DLL loaded from a user-writable directory<br />  (<code>C:\Users\</code>, <code>C:\Temp\</code>, <code>AppData\</code>)</p>
</li>
<li><p>A high-integrity or SYSTEM process loading a DLL from a non-standard location</p>
</li>
<li><p>An unsigned DLL loaded into a signed system binary</p>
</li>
<li><p>A recently created DLL file followed by immediate process execution</p>
</li>
<li><p>“NAME NOT FOUND” events before a successful DLL resolution</p>
</li>
</ul>
<p>These anomalies deviate from normal Windows module loading behavior.</p>
<p><strong><mark>Log Sources Required</mark></strong></p>
<p>To properly detect this technique, enable:</p>
<ul>
<li><p><strong>Sysmon Event ID 7</strong> (Image Load)</p>
</li>
<li><p><strong>Sysmon Event ID 11</strong> (File Creation)</p>
</li>
<li><p>Windows Security 4688 (Process Creation)</p>
</li>
</ul>
<p>Without module load logging, DLL hijacking becomes harder to detect.</p>
<p><strong><mark>Splunk Query</mark></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771418040206/8b061698-423f-4ae2-98c4-952fd02548c3.png" alt /></p>
<p><strong><mark>Sigma Detection Rule</mark></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771418163239/2f80efbe-4b78-49aa-946e-0b1ad29cc363.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item></channel></rss>