{"id":10115,"date":"2025-08-19T22:31:42","date_gmt":"2025-08-19T22:31:42","guid":{"rendered":"https:\/\/www.hexacorn.com\/blog\/?p=10115"},"modified":"2025-09-03T23:42:33","modified_gmt":"2025-09-03T23:42:33","slug":"dll-forwardsideloading","status":"publish","type":"post","link":"https:\/\/www.hexacorn.com\/blog\/2025\/08\/19\/dll-forwardsideloading\/","title":{"rendered":"DLL ForwardSideloading"},"content":{"rendered":"\n<p>Some DLLs export functions (via export table) that are just forwarding execution to functions implemented in other libraries. It&#8217;s a very common practice and one of the most known forwards are:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kernel32.dll HeapAlloc -&gt; NTDLL.RtlAllocateHeap<br>kernel32.dll HeapReAlloc -&gt; NTDLL.RtlReAllocateHeap<br>kernel32.dll HeapSize -&gt; NTDLL.RtlSizeHeap<\/pre>\n\n\n\n<p>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. &#8212; ones that are on the KnownDLLs list + very often already loaded into memory.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>Meaning?<\/p>\n\n\n\n<p>Use a signed rundll32.exe to load a signed DLL that will then load the payload DLL of our choice&#8230; by using that exported function.<\/p>\n\n\n\n<p>This is a <a href=\"https:\/\/hexacorn.com\/d\/apis_fwd.txt\">list of forwards<\/a> I have generated.<\/p>\n\n\n\n<p>We can quickly identify a non-KnownDlls pair, where:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">keyiso.dll KeyIsoSetAuditingInterface -&gt; NCRYPTPROV.SetAuditingInterface<\/pre>\n\n\n\n<p>So, copying <em>keyiso.dll<\/em> to c:\\test, and then placing a payload in <em>NCRYPTPROV.dll<\/em> in the same folder, and then finally executing:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">rundll32.exe c:\\test\\keyiso.dll, KeyIsoSetAuditingInterface<\/pre>\n\n\n\n<p>will load a copy of the <em>keyiso.dll<\/em> first, then the function resolution of <em>KeyIsoSetAuditingInterface<\/em> will resolve it first to <em>NCRYPTPROV.SetAuditingInterface<\/em> forward, and then automatically load the <em>NCRYPTPROV.dll<\/em>, and only then execute the function&#8217;s code. In the example below, I didn&#8217;t bother to implement <em>SetAuditingInterface<\/em> in the test DLL, just to showcase the execution flow leading to (actually misleading, since it refers to the outer DLL\/API name combo) &#8216;missing API&#8217; message box.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/08\/keyiso.png\"><img decoding=\"async\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/08\/keyiso.png\" alt=\"\" class=\"wp-image-10118\" width=\"512\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/08\/keyiso.png 634w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/08\/keyiso-300x232.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2025\/08\/keyiso-388x300.png 388w\" sizes=\"(max-width: 634px) 100vw, 634px\" \/><\/a><\/figure>\n\n\n\n<p>The <em>DLLMain_64_DLL_PROCESS_ATTACH.txt<\/em> file is created by the test payload, indicating its DllMain function has been executed.<\/p>\n\n\n\n<p>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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some DLLs export functions (via export table) that are just forwarding execution to functions implemented in other libraries. It&#8217;s a very common practice and one of the most known forwards are: kernel32.dll HeapAlloc -&gt; NTDLL.RtlAllocateHeapkernel32.dll HeapReAlloc -&gt; NTDLL.RtlReAllocateHeapkernel32.dll HeapSize -&gt; &hellip; <a href=\"https:\/\/www.hexacorn.com\/blog\/2025\/08\/19\/dll-forwardsideloading\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[129,56,64,61],"tags":[],"_links":{"self":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/10115"}],"collection":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/comments?post=10115"}],"version-history":[{"count":5,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/10115\/revisions"}],"predecessor-version":[{"id":10122,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/10115\/revisions\/10122"}],"wp:attachment":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/media?parent=10115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/categories?post=10115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/tags?post=10115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}