If an attacker can make a trusted process load their library, their code runs with that process's identity, signature and reputation, and M1044 Restrict Library Loading is the ATT&CK mitigation aimed at closing that door. MITRE ATT&CK v20 describes M1044 as controls that ensure only trusted and verified libraries (DLLs, shared objects) are loaded into processes, citing DLL injection, DLL search order hijacking and LD_PRELOAD abuse. This guide maps the mitigation to the techniques ATT&CK links it to, explains the Windows and Linux settings that implement it, sets out what it does not cover and how to measure it. It is written for Windows and Linux platform engineers, application owners and detection engineers.
Key takeaways
- Three technique mappings, one family. In ATT&CK v20, M1044 mitigates T1574 Hijack Execution Flow, T1574.001 DLL and T1547.008 LSASS Driver.
- Safe DLL search mode is a baseline, not a fix. It is on by default and only moves the current folder later in the search order; the application folder and PATH remain searchable.
- The strongest controls live in the application. Fully qualified paths and SetDefaultDllDirectories with LOAD_LIBRARY_SEARCH flags remove whole classes of hijack, so developer guidance is part of M1044.
- Linux has a built-in safeguard for privileged binaries. In secure-execution mode the dynamic linker ignores LD_LIBRARY_PATH and restricts LD_PRELOAD, but /etc/ld.so.preload and writable library paths still need integrity monitoring.
- Library loading is enforced best with application control. ATT&CK itself points to signed-library enforcement with WDAC, AppLocker or SELinux, which links M1044 to M1038 Execution Prevention and M1045 Code Signing.
What M1044 asks a team to implement
| ATT&CK v20 measure | Windows implementation | Linux implementation |
|---|---|---|
| Safe library loading practices | Keep SafeDllSearchMode enabled; disallow loading of remote DLLs | Restrict LD_PRELOAD and LD_LIBRARY_PATH use |
| Code signing enforcement for libraries | App Control for Business (WDAC) policies that cover DLLs; signature checks with Signtool | Signed packages and repository trust; integrity of library directories |
| Environment hardening | Remove write access for standard users from application and PATH directories | Protect /etc/ld.so.conf, /etc/ld.so.conf.d and /etc/ld.so.preload; ATT&CK mentions ldconfig and chattr |
| Audit and monitor library loading | Sysmon Event ID 7 (image loaded) | auditd watches on library paths and linker configuration files |
| Application control | AppLocker DLL rules or WDAC | SELinux or AppArmor policies |
ATT&CK's description also names file integrity monitoring tools as cross-platform options; any tool that alerts on unexpected changes to library directories meets the intent.
Techniques M1044 mitigates in ATT&CK v20
| Tactic | Technique | What ATT&CK says M1044 does | Priority |
|---|---|---|---|
| Stealth, Execution | T1574 Hijack Execution Flow | Disallow loading of remote DLLs (default from Windows Server 2012); enable Safe DLL Search Mode so system directories are searched before local ones; configurable through the MSS (Legacy) Group Policy "MSS: (SafeDllSearchMode) Enable Safe DLL search mode" | High |
| Stealth, Execution | T1574.001 DLL | Disallow remote DLL loading and keep Safe DLL Search Mode on, which moves the user's current folder later in the search order | High |
| Persistence, Privilege Escalation | T1547.008 LSASS Driver | Ensure SafeDllSearchMode is enabled to reduce the risk that lsass.exe loads a malicious library | Medium |
The mapping is short because ATT&CK v20 merged several earlier DLL sub-techniques into T1574.001 DLL (the former DLL Side-Loading sub-technique T1574.002 is revoked). Note also that T1574.006 Dynamic Linker Hijacking is not one of M1044's v20 relationships even though the M1044 description discusses LD_PRELOAD, so its coverage is something you add, not something ATT&CK credits. Linked technique guides: T1574 Hijack Execution Flow Defensive Guide, MITRE ATT&CK T1574.001 Hijack Execution Flow and T1547 Boot or Logon Autostart Execution.
Windows: how the search order shapes the risk
Microsoft documents the standard search order for unpackaged desktop applications with safe DLL search mode enabled. Knowing it tells you which directories must not be writable by low-privileged users.
| Order | Location | Hijack exposure |
|---|---|---|
| 1 to 4 | DLL redirection, API sets, side-by-side manifest redirection, loaded-module list | Low; redirection files and manifests still need protecting |
| 5 | Known DLLs (HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs) | Low; the system uses its own copy |
| 6 | Package dependency graph (Windows 11 21H2 and later) | Low |
| 7 | The folder the application loaded from | High if the application folder is user-writable (common for per-user installs and tools copied to Downloads) |
| 8 to 10 | System folder, 16-bit system folder, Windows folder | Low if ACLs are default |
| 11 | Current folder | Medium; moved here by safe mode (with safe mode off it sits right after the application folder) |
| 12 | Directories in PATH | High if any PATH entry is user-writable |
What the registry setting does: SafeDllSearchMode under HKLM\System\CurrentControlSet\Control\Session Manager is enabled by default; setting it to 0 disables it. Microsoft also notes that calling SetDllDirectory effectively disables safe mode while that folder is in the search path.
Application-level controls (developer guidance)
Microsoft's Dynamic-link library security guidance gives the controls that remove the hijack rather than reorder it:
- Fully qualified paths: specify a full path when calling LoadLibrary, LoadLibraryEx, CreateProcess or ShellExecute.
- Process-wide search order: call SetDefaultDllDirectories with LOAD_LIBRARY_SEARCH flags (for example LOAD_LIBRARY_SEARCH_APPLICATION_DIR and LOAD_LIBRARY_SEARCH_SYSTEM32) early in startup, or pass LOAD_LIBRARY_SEARCH_SYSTEM32 to LoadLibraryEx for system libraries.
- Remove the current directory: call SetDllDirectory with an empty string once, early in process initialisation.
- Use redirection or manifests so the application binds to the intended DLL.
- Safe SearchPath: if SearchPath is used to locate a DLL, call SetSearchPathMode with BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE first.
Microsoft also describes a Process Monitor test: filter on CreateFile and LoadImage operations for .dll and similar extensions, exclude successes, start the application from a chosen working directory and look for loads attempted from that directory. This is a practical acceptance test for in-house and procured software. See M1013 Application Developer Guidance for building it into the SDLC.
Linux: the dynamic linker controls
- Secure-execution mode: the ld.so manual states that when AT_SECURE is set (set-user-ID or set-group-ID programs, binaries with file capabilities run by non-root processes, or when a Linux Security Module sets it), LD_LIBRARY_PATH is ignored, LD_PRELOAD entries containing slashes are ignored, and preloads come only from standard directories and only if they have the set-user-ID bit. This protects privileged binaries, not ordinary user processes or services.
- /etc/ld.so.preload: a system-wide list of objects loaded into every dynamically linked program. It should normally be absent or empty; any content needs a known owner and change record.
- /etc/ld.so.conf and /etc/ld.so.cache: the cache, built by ldconfig, is consulted before the default /lib and /usr/lib paths. Directories added through ld.so.conf.d therefore need the same ownership and permission review as system library directories.
- Environment variables for services: check systemd unit Environment= lines, container images and CI runners for LD_PRELOAD or LD_LIBRARY_PATH set to writable locations. See M1039 Environment Variable Permissions.
- Mandatory access control: SELinux or AppArmor profiles that restrict which files a confined service may map as executable cover the same ground as Windows DLL rules.
Where identity fits: service accounts and build runners
A hijacked library inherits the identity of the process that loads it. When that process runs as a service account, a CI/CD runner or a management agent with broad rights, library hijack becomes a way to act as that non-human identity without stealing its credentials. NHI Mgmt Group recommends:
- Prioritise services by identity privilege: apply M1044 testing first to binaries that run as SYSTEM, root, domain service accounts or deployment identities.
- Keep install directories of privileged services admin-writable only: a service account should not be able to write to its own binary folder.
- Treat build agents as high-value hosts: runner images and toolchains are frequent targets for library and toolchain tampering. See MITRE ATT&CK T1554 Compromise Host Software Binary.
Gaps: what M1044 does not stop
| Gap | Why | Pair with |
|---|---|---|
| Hijack through the application's own folder | Safe search mode still searches the application folder first | File and directory permissions (M1022), application control covering DLLs |
| A signed but vulnerable or abused library | Signature checks trust the publisher, not the behaviour | Allowlists by hash or specific file, behaviour prevention on endpoint (M1040) |
| T1055.001 Dynamic-link Library Injection | Injection writes into a running process rather than abusing search order | Behaviour prevention, privileged process integrity (M1025) |
| T1574.006 Dynamic Linker Hijacking for ordinary processes | Secure-execution mode only applies to privileged binaries | MAC policy, environment control, integrity monitoring |
| Attacker with administrator or root rights | They can change policy, ACLs and linker configuration | Tamper protection, privileged account management, alerting on configuration change |
Implementation priorities
- Confirm the baseline: report SafeDllSearchMode (absent or 1) across Windows, and confirm no device has it set to 0.
- Find writable search locations: enumerate PATH entries and service binary folders writable by non-administrators; on Linux, check library directories, ld.so.conf.d and ld.so.preload ownership.
- Turn on load telemetry: Sysmon Event ID 7 with a filtered configuration (unsigned images, loads from user-writable paths), and auditd watches on linker configuration files. See the Sysmon Guide.
- Audit application control for DLLs: run WDAC or AppLocker DLL rules in audit mode on a pilot ring; DLL rules have a larger performance and compatibility footprint than executable rules, so measure before enforcing. See App Control for Business (WDAC).
- Fix the applications: feed Process Monitor findings back to developers and suppliers; require SetDefaultDllDirectories or full paths in new code.
- Enforce in rings, keep rollback: move policies to enforcement for privileged services first, keep the previous policy version ready to redeploy, and document exceptions with an owner and expiry.
Detection and measurement
| Metric | Target |
|---|---|
| Windows devices with SafeDllSearchMode disabled | Zero |
| User-writable directories in system PATH or in privileged service folders | Zero, or documented exceptions |
| Privileged services tested with the Process Monitor procedure | 100% of tier 0 and tier 1 services |
| Linux hosts with a non-empty /etc/ld.so.preload without a change record | Zero |
| Unsigned DLL loads into privileged processes (Sysmon Event ID 7) | Trending to zero, every instance triaged |
Framework mapping and related countermeasures
| Framework | Item | Relationship |
|---|---|---|
| MITRE D3FEND | D3-SCF System Call Filtering | The D3FEND ontology relates M1044 to this countermeasure and comments that it is one possible way to filter library loading |
| MITRE ATT&CK | M1038 Execution Prevention, M1045 Code Signing | Related mitigations: enforce which libraries may load |
| MITRE ATT&CK | M1022 Restrict File and Directory Permissions | Related mitigation: closes writable search locations |
| MITRE ATT&CK | M1013 Application Developer Guidance | Related mitigation: safe loading in code |
Common failure patterns
- Counting SafeDllSearchMode as coverage: it is a default setting that leaves the application folder and PATH exposed.
- Per-user installs of privileged tools: software installed into user profiles but run elevated searches a folder the user can write.
- PATH entries added by installers: a writable directory early in the system PATH affects every process that relies on PATH resolution.
- Executable-only application control: policies that cover .exe files but not DLLs leave library hijack untouched.
- Ignoring Linux linker configuration: ld.so.preload and ld.so.conf.d changes are not monitored, and services inherit LD_PRELOAD from unit files or images.
Practitioner checklist
- Confirm SafeDllSearchMode is not disabled on any Windows device.
- Remove user-writable directories from system PATH and privileged service folders.
- Collect Sysmon Event ID 7 for loads from user-writable paths and unsigned images.
- Pilot WDAC or AppLocker DLL rules in audit mode before enforcing.
- Run the Microsoft Process Monitor test on privileged in-house and procured software.
- Require SetDefaultDllDirectories or fully qualified paths in coding standards.
- Monitor /etc/ld.so.preload, /etc/ld.so.conf.d and library directories with auditd or FIM.
- Review service units, images and runners for LD_PRELOAD and LD_LIBRARY_PATH.
Standards and references
- MITRE ATT&CK: M1044 Restrict Library Loading
- MITRE ATT&CK: T1574.001 DLL
- MITRE D3FEND: System Call Filtering
- Microsoft Learn: Dynamic-link library search order
- Microsoft Learn: Dynamic-link library security
- Linux man-pages: ld.so(8)
Related NHI Mgmt Group resources: T1574 Hijack Execution Flow Defensive Guide · App Control for Business (WDAC) · Sysmon Guide · M1043 Credential Access Protection · M1045 Code Signing