Beyond good ol’ Run key, Part 88

This is one more post to describe a case where I came across a Windows feature and then wanted to analyze how the whole thing works only to find out someone already did it before…

Windows Error Reporting allows the applications to register ‘custom runtime exception handler that is used to provide custom error reporting for crashes’ via WerRegisterRuntimeExceptionModule API.

In practice, the application needs to add a name of the DLL under this key:

  • HKLM\SOFTWARE\Microsoft\Windows\
    Windows Error Reporting\
    RuntimeExceptionHelperModules

and then call the WerRegisterRuntimeExceptionModule API.

When crash occurs the WER engine enumerates all the registered runtime exception handlers for the application and loads them via LoadLibrary and calls their functions exported allowing them to ‘claim’ this particular crash. It only loads the DLLs registered via WerRegisterRuntimeExceptionModule  though. This is a bit of a limitation, but one could discover the presences of such exception helper module and swap it so that next time the other application (the one that registered it) crashes, the swapped DLL will be loaded.

This allows to not only achieve a persistence (although not very reliable as it depends on a crash of some application), but also load the code into the space of WER process – most likely under the nose of many security applications/reversers. As such, it could be a potential sandbox/EDR evasion — register the DLL, call WerRegisterRuntimeExceptionModule, crash your app, the DLL will be loaded under WerFault.exe process. In another scenario one .exe could add the registry entry only, launch the second stage .exe and quit. The second stage would call WerRegisterRuntimeExceptionModule and crash. Both applications would do almost nothing while it’s the exception handler DLL that would do the main work under the Werfault.exe process.

You can see the full example here and an old article on the same topic.

Beyond good ol’ Run key, Part 87

How many ntdll does it take to change a light bulb?

For 32-bit processes on 32-bit systems – 1.

For 32-bit processes on 64-bit systems – 2.

But… are you sure?

Turns out that newer versions of Windows allow one more. It’s called a Delegated NTDLL.

When I discovered it during one of my Procmon sessions:

… I immediately googled it and found out that redplait was the first one to describe this mechanism in detail, and then there was also an article on StackOverflow about it; still, since it’s not very well-known I decided to include it in this series anyway.

How to use it?

  • Build a DLL that exports the export functions as listed in redplait’s post:
    • KiRaiseUserExceptionDispatcher
    • KiUserApcDispatcher
    • KiUserCallbackDispatcher
    • KiUserExceptionDispatcher
    • LdrInitializeThunk
    • LdrParentInterlockedPopEntrySList
    • LdrParentRtlInitializeNtUserPfn
    • LdrParentRtlResetNtUserPfn
    • LdrParentRtlRetrieveNtUserPfn
    • LdrpChildNtdll
    • LdrSystemDllInitBlock (this one is actually a pointer that must point to a dword storing a value identical with the one stored in the ntdll the delegated ntdll is for and equal e.g. 224 /0xE0/)
    • RtlDispatchAPC
    • RtlUserThreadStart
  • Drop it in the system32 directory.
  • Set up the respective IFEO key for the victim application of choice:
    • HKLM\SOFTWARE\Microsoft\Windows NT\
      CurrentVersion\Image File Execution Options\
      <filename>\DelegatedNtdll=<filenameonly>

and you are set. Next time the program is ran it will load the dll.

Note that the DLL must include the exports otherwise it won’t be executed (not even DllMain) – this is because the ntdll loads it not via LdrLoadDll, but via NtCreateSection/ZwMapViewOfSection/RtlImageNtHeader and then walks through a list of exports that it tries to resolve using LdrpGetProcedureAddress.