DLL ForwardSideloading, Part 2

The 2nd part following my first take on this subject was kinda inevitable.

Why?

Sixtyvividtails is one of my fav researchers, because a) he reads my posts, breaks them apart, and usually comes up with some amazing/creative comments/additional thoughts that often lead us to some new, cool discoveries (see f.ex. this) b) he also made a social media bet that I (obviously) couldn’t leave unchallenged. Thank you Sixtyvividtails, you are an inspiration and I love your research and creative ideas a lot!

So, to business…

My first find was this unsigned Realtek DLL (RealWoWDLL.dll – VT Link) that exported the intriguing forward:

testker -> kerberos.Spinitialize

Then… I went for holidays 🙂

I did go there with an idea though that after coming back I will do a more structured follow-up research…

So when I came back, I immediately got to work.

The first target was an obvious one – run the very same forwarder-extractor script over the Windows 2025 server files. The results are here. Many of these combos can be used for DLL ForwardSideloading.

The second target was bigger. I checked my repo of ‘good’ files only to discover that I am sitting on around 700K ‘clean’ DLLs, both 32- and 64-bit. Sadly, I don know which ones of them are truly signed or not, unless the actual PE file of the DLL is physically signed (aka not via a catalogue). Still, 700K files is a lot, and there is a hope that it’s worth analyzing them all to see how many of them are non-Microsoft, and actually use/leverage the forwarded exports…

So, I ran my script over the last weekend and after few days it spat out its results.

And here’s the catch:

  • yes, some vendors do appear to be using forwarded functions same as Microsoft and Realtek
  • many functions that have their names exported by DLLs (mapping present in the export table) are not necessarily meant to be used by any other program, but since some do include a “.” character in their name, they could actually be used to facilitate DLL ForwardSideloading !

See the (filtered) results here.

DLL ForwardSideloading

Some DLLs export functions (via export table) that are just forwarding execution to functions implemented in other libraries. It’s a very common practice and one of the most known forwards are:

kernel32.dll HeapAlloc -> NTDLL.RtlAllocateHeap
kernel32.dll HeapReAlloc -> NTDLL.RtlReAllocateHeap
kernel32.dll HeapSize -> NTDLL.RtlSizeHeap

Now, most of us assume that lots of forwards redirect the execution to most popular Windows DLLs, and these are typically just your regular KnownDLLs: ntdll, kernelbase, ole32, etc. — ones that are on the KnownDLLs list + very often already loaded into memory.

I decided to check what forwards we can find on the Win 11 OS, because I had a cunning plan: If I can find a forward that does not redirect to KnownDlls, then I can execute an indirect DLL sideloading, one that is on par with traditional EXE sideloading technique.

Meaning?

Use a signed rundll32.exe to load a signed DLL that will then load the payload DLL of our choice… by using that exported function.

This is a list of forwards I have generated.

We can quickly identify a non-KnownDlls pair, where:

keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface

So, copying keyiso.dll to c:\test, and then placing a payload in NCRYPTPROV.dll in the same folder, and then finally executing:

rundll32.exe c:\test\keyiso.dll, KeyIsoSetAuditingInterface

will load a copy of the keyiso.dll first, then the function resolution of KeyIsoSetAuditingInterface will resolve it first to NCRYPTPROV.SetAuditingInterface forward, and then automatically load the NCRYPTPROV.dll, and only then execute the function’s code. In the example below, I didn’t bother to implement SetAuditingInterface in the test DLL, just to showcase the execution flow leading to (actually misleading, since it refers to the outer DLL/API name combo) ‘missing API’ message box.

The DLLMain_64_DLL_PROCESS_ATTACH.txt file is created by the test payload, indicating its DllMain function has been executed.

Obviously, this technique does not need to rely on OS libraries. I am pretty sure that a bigger study of exported functions from a larger corpora of signed DLLs will yield a set of combos that can be used to implement this technique.