How can I try to escape the disease-ridden hot-tubs known as the TEMP and Downloads directories?
Some time ago, I described the TEMP directory as a hot tub whose water hasn’t been changed in over a year. The Downloads folder is in a similar situation: There’s all sorts of unrelated junk in there, some of which may not be very friendly to your health.
Starting in Windows 10 Version 1607,¹ you can set attributes on your executable to tell the system how to look for the DLLs to which your executable links statically.² To do this, pass the
/DEPENDENTLOADFLAG:nnnn command line option to the linker, where
nnnn is a value corresponding to some combination of the
LOAD_ values that can be passed to the
By far the most useful value is
LOAD_, which means “Look in the system32 directory and nowhere else.”
To do this, pass
Versions of Windows that do not support this option merely ignore it, so it’s okay to set this option unconditionally.
¹ Windows 10 Version 1607 goes by several other names: The Anniversary Update, Build 14393, and the RS1 release. It’s kind of silly, really.
² Note that the dependent load flag applies only to DLLs that are loaded as a consequence of resolving the module’s static imports. DLLs loaded dynamically via
LoadLibraryEx follow the normal rules.
Huh? Why did the article’s subject suddenly change in the middle of it?
The post starts on the subject of the TEMP folder. Suddenly, it turns into random nonsense about DLLs, compiling, and the SYSTEM32 folder! It is as if the second paragraph and beyond are copied and pasted from somewhere else.
This looks like Franeknstein’s blog post. Frankenblog… or Frankenpost.
Maybe it’s RaymondGPT-3
You should read the linked article first.
Since the executable directory is also the application directory, DLLs get loaded from there first, which poses a problem if the executable is placed in a directory filled with other junk, like the temporary folder or the Downloads folder (you don’t want your application loading a random DLL just because the user downloaded one).
If you don’t / can’t use the switch, the solution is to create a new subdirectory and put the executable into it.
It’s all part of the same thing. First, Raymond starts talking about the problem of the “disease filled hot tub”, which is a way to say that the Temp and Downloads directories can contain unwanted (or even malicious) versions of the DLLs your process loads. Then, he describes a technique to tell the OS to ignore those DLLs and force it to only load them from System32.
No, I think the point here is that your application may have been downloaded to the download folder or expanded into the TEMP folder. The default behaviour for DLL resolution involves looking in the directory where the application is located which may be infested with all sorts of DLLs that are not the correct ones (and may take precedence over the ones you actually want e.g. in System32).
So of course I *immediately* on learning of this flag’s existence go set it on our setup bootstrapper. We had previously been relying on knowndlls and careful coding to make this safe. Now we still rely on careful coding but the dependency on knowndlls is dropped.
And I get a nice undocumented linker warning LNK4266 missing load config symbol for image built with /DEPENDENTLOAGFALG and have no idea what it means.
Maybe because you have a typo in there.
You could have read https://skanthak.homepage.t-online.de/snafu.html since more than 5 (in words: FIVE) years; or FullDisclosure since more than 3 years: https://seclists.org/bugtraq/2020/Jan/41
I reported this bug in LINK.exe a loooong time ago to the MSRC; their response was “not security relevant;; we’ll forward it to the product team” — and then all of them went back to sleep again.
JFTR: the “PE Format” documentation https://msdn.microsoft.com/en-us/library/gg463119.aspx#the-load-configuration-structure-image-only alias https://msdn.microsoft.com/en-us/library/ms680547.aspx#the-load-configuration-structure-image-only still tells a blatant lie: The Microsoft linker automatically provides a default load configuration structure to include the reserved SEH data.
Since Windows 7, relying on KnownDlls is subject to failure: see https://seclists.org/fulldisclosure/2020/Dec/37 and https://skanthak.homepage.t-online.de/detour.html for an example.
And since Windows XP they can be overridden per application manifest.
Well, this seems to work properly with 17.5.
Start the VC/VS command prompt and run the following 3 command lines:
Does the last one display the load configuration?
PSA: XP and older will only accept the original struct size because it checks if the directory entry size == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY). I guess the program will still work? but imagehlp.dll and other things might not be happy. IMAGE_LOAD_CONFIG_DIRECTORY::Size is allowed to be 0, this indicates the original struct. The Size field was not even named Size originally (the PE spec documentation still calls it Characteristics).
But how is this attribute stored in the PE file?
From the Microsoft official PE Format documentation, this is in the Load Config Table data directory. This data directory corresponds to the IMAGE_LOAD_CONFIG_DIRECTORY structure that you can find in winnt.h. This has a field named DependentLoadFlags, so I would imagine that this is where it is stored.
Quite surprised this isn’t in the normal linker options pages. Either way set on my little utility that is very likely to be affected by this and would have been best having this set ages ago.
Of course some good guy working for our beloved manufacturer who really cares about the security of Windows and its users^Wcustomers might add the NTFS ACE (D;OIIO;WP;;;WD) to %SystemRoot%\Temp\ and %SystemRoot%\SystemTemp\ as well as all %USERPROFILE%\Downloads\ and all %LOCALAPPDATA%\Temp\ directories — better yet to every %USERPROFILE%\, to %PUBLIC%\, to %ProgramData%\, to %SystemRoot%\DriverStore\ etc.
Since sometime in the palaeozoic, all my systems wipe the TEMP directory on boot. Good point about the Downloads directory though, I should add a “delete items over age X” thing to it.