# Library path hijack via loader search

Empty or attacker-writable loader path entries resolving library names to untrusted locations

_Area: Memory corruption and native code. Seen in 3 disclosed reports; latest 2026-03-06. Updated 2026-11-02._

## How it works
A loader (dynamic linker, .NET runtime, Windows DLL loader) resolves a library name by walking a search list built from environment variables, config files, or the host's own directory. The broken assumption is that every entry points somewhere trusted. When an entry is empty, relative, or writable by a lower-privileged party, the loader silently picks up an attacker-supplied library of the same name and runs its code inside the trusted process. Empty `LD_LIBRARY_PATH` segments are read as the current working directory [E1](https://bugbountylibrary.com/r/h1%3A1073202.md); `.exe.config` and `APPDOMAIN_MANAGER_*` variables name an assembly the runtime loads without checking trust [E3](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md); signed binaries load a same-directory DLL [E2](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md).

## Where it shows up
- Generated wrapper/launcher scripts that build `LD_LIBRARY_PATH`/`LD_PRELOAD` with empty, unquoted, or relative segments [E1](https://bugbountylibrary.com/r/h1%3A1073202.md)
- Signed executables that load a DLL from their own directory rather than a protected path [E2](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md)
- `.exe.config` with `appDomainManagerAssembly`/`appDomainManagerType`, or `APPDOMAIN_MANAGER_ASM`/`APPDOMAIN_MANAGER_TYPE` env vars [E3](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md)
- Any config knob or env var that selects a library/assembly path at startup

## How to review
Find every place a library name is resolved and ask: which directories can appear in the search list, and who can write to them? The invariant: every resolved path must be absolute, non-empty, and inside a directory the launching user cannot modify. Check that generated scripts never emit empty or relative path segments [E1](https://bugbountylibrary.com/r/h1%3A1073202.md); that signed hosts load dependencies from System32 or a verified absolute path, not CWD [E2](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md); that app-domain manager settings are absent or point at a trusted, signed assembly [E3](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md). Treat any writable directory containing the host binary as a hijack surface.

## How finders spotted it
- Read generated wrapper scripts, noticed empty `LD_LIBRARY_PATH` variables, recalled the linker's empty-means-CWD quirk, then confirmed with a crafted `libc.so.6` [E1](https://bugbountylibrary.com/r/h1%3A1073202.md)
- Examined the .NET app-domain initialization mechanism and legitimate config features, recognizing they redirect assembly loading under trusted binaries [E3](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md)
- (E2's finder reached the sideload only after retroactive IOC hunting surfaced reverse-tunnel command lines; the sideload was identified during that follow-up, not from path analysis)

## Variants seen
- Empty path segment in a generated launcher resolving to CWD [E1](https://bugbountylibrary.com/r/h1%3A1073202.md)
- Same-directory DLL sideloading by a signed host [E2](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md)
- Config-file and environment-variable assembly redirection in .NET [E3](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md)

## Impact and severity
Code execution inside a trusted process. In Snapcraft this reached container escape via the X11 plug and access to dotfiles and non-home files [E1](https://bugbountylibrary.com/r/h1%3A1073202.md). The env-var variant propagates to child processes, chaining across .NET apps in a session [E3](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md). In the intrusion, the sideload gave the attacker a C2 channel, but the escalation to domain-wide lateral movement came from the intrusion chain, not the hijack pattern alone [E2](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md). Severity rises with the privilege of the hijacked host and how far the loader's search reaches.

## Seen in real software
Open-source packages and projects, and products, where this pattern was found. If the target runs one, compare the version it runs with the fix.
- **Fortemedia FMAPP** (FMAPP.dll) (version not stated): Unmasking an Attack Chain of MuddyWater. Report: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md
- **.NET Framework** (app domain initialization / assembly resolution) (version not stated): Hiding in Plain Sight with App Domain Manager Injection. Report: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1073202.md
- E2: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-muddywater-attack-chain.md
- E3: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-app-domain-manager-injection.md
