Technical debt of C:\Windows\System path

Thanks to @sixtyvividtails who corrected a mistake I made in the earlier version of the post

Updated post

One of a less known paths that is being searched when the libraries are loaded is C:\Windows\System.

Anytime the search for a library kicks off, the following system directories are being searched:

  • C:\Windows\System32\
  • C:\Windows\System\

We can clearly see this in Procmon when we try to test the POC from my post about UpdateAPI.dll:

So, that old 16-bit legacy path is still there, even if practically no one is using it today. As such, we can use this path to drop at least some of the payloads there.

Rundll32 and Phantom DLL lolbins, 32-bit version

As I have shown in the last post, there exists a class of DLLs on Windows OS that load other libraries via import table, and sometimes these needed imported libraries do not exist. This creates an opportunity that we can leverage f.ex. by using rundll32.exe to load these ‘broken’ libraries, and to avoid them failing to load because of missing libraries – we provide these as a payload, saved in an appropriately named DLL files (in essence, they are phantom DLLs) .

The previous post discussed 64-bit libraries, and here I will demo a single instance of a 32-bit library like this:

uxlib.dll on Windows 11 Pro 22H2

It imports IsCrossArchitectureInstall API from WDSUTIL.dll, so providing our own will lead to this: