exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft Windows 10 DLL Search Path

Microsoft Windows 10 DLL Search Path
Posted Jan 29, 2020
Authored by Stefan Kanthak

With Windows 10 1607, Microsoft introduced the /DEPENDENTLOADFLAG linker option, a security feature to restrict or limit the search path for DLLs. Two bugs exist with this attempt to limit access.

tags | advisory
systems | windows
SHA-256 | 04f3f470ca90a3089624ef754a9f8aa5c4419a8bfbfe2910545dd4901e3c35cf

Microsoft Windows 10 DLL Search Path

Change Mirror Download
Hi @ll,

(a long[er] form of the following advisory is available at
<https://skanthak.homepage.t-online.de/snafu.html>)

With Windows 10 1607, Microsoft introduced the /DEPENDENTLOADFLAG
linker option, a security feature to restrict or limit the search
path for DLLs:

| On supported operating systems, this option has the effect of
| changing calls to LoadLibrary("dependent.dll") to the equivalent
| of LoadLibraryEx("dependent.dll", 0, load_flags).
...
| This flag can be used to make DLL planting attacks[*] more difficult.
...
| An option of /DEPENDENTLOADFLAG:0x800 is even more restrictive,
| limiting search to the %windows%\system32 directory.

[*] DLL planting attacks referred to "Dynamic-Link Library Security"
<https://msdn.microsoft.com/en-us/library/ff919712.aspx>

The above quote was taken from
<https://docs.microsoft.com/en-us/cpp/build/reference/dependentloadflag>
before 2020-01-22; according to it /DEPENDENTLOADFLAG applies to
RUNTIME linking via LoadLibrary() ... which it but WRONG.


Demonstration:
~~~~~~~~~~~~~~

0. on a current installation of Windows 10, start the command prompt
of the Windows Development Kit and run the following two commands:

Set CL=/Iwindows.h /W4 /Zl
Set LINK=/DEPENDENTLOADFLAG:0x800 /DYNAMICBASE /NXCOMPAT /RELEASE /SUBSYSTEM:CONSOLE

1. build a minimal SNAFU.DLL from the following source file SNAFU.C

__declspec(dllexport)
BOOL WINAPI _DllMainCRTStartup(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}

with the following command:

CL.EXE /LD SNAFU.C /link /ENTRY:_DllMainCRTStartup /EXPORT:_DllMainCRTStartup

2. build a minimal application SNAFU.EXE from the following source
file SNAFU.C

__declspec(noreturn)
VOID WINAPI mainCRTStartup(VOID)
{
HMODULE hModule = LoadLibraryA("SNAFU.DLL");

if (hModule == NULL)
ExitProcess(GetLastError());

if (!FreeLibrary(hModule))
ExitProcess(GetLastError());

ExitProcess(0);
}

with the following command:

CL.EXE SNAFU.C /link /DEFAULTLIB:kernel32.lib /ENTRY:mainCRTStartup

3. run the application SNAFU.EXE and display its exit code with
the following commands:

.\SNAFU.EXE
Echo %ERRORLEVEL%

The exit code is 0, proving that /DEPENDENTLOADFLAG:0x800
does NOT limit the DLL search path for LoadLibrary() to
%SystemRoot%\System32\!

4. when you change the return value of the DLL's entry point
function _DllMainCRTStartup() to FALSE, the exit code is
1114 alias ERROR_DLL_INIT_FAILED, again proving that
/DEPENDENTLOADFLAG:0X800 does NOT work as documented above.


Due to its security impact (see "Dynamic-Link Library Security")
I reported this bug (plus two bugs in LINK.EXE, which fails to
set /DEPENDENTLOADFLAG in executable files; see the full story at
<https://skanthak.homepage.t-online.de/snafu.html>) to Microsoft's
Security Response Center, where MSRC Case 56011 was opened.

They replied to the bug demonstrated above with the following
statement, IGNORING the bugs reported against LINK.EXE completely:

| The team has finished their investigation and determined the way
| they will address this report is via a documentation update of
| https://docs.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=vs-2019.
|
| It wasn't supposed to say that LoadLibrary will act as LoadLibraryEx,
| specifically this statement:
|
| On supported operating systems, this option has the effect of
| changing calls to LoadLibrary("dependent.dll") to the equivalent
| of LoadLibraryEx("dependent.dll", 0, load_flags). Calls to
| LoadLibraryEx are unaffected. This option doesn't apply
| recursively to DLLs loaded by your app.


On 2020-01-24 the documentation update went live; it now reads:

| Sets the default load flags used when the operating system resolves
| the statically linked imports of a module.
|
| /DEPENDENTLOADFLAG[:load_flags]
|
| load_flags
| An optional integer value that specifies the load flags to apply
| when resolving statically linked import dependencies of the module.
| The default value is 0. For a list of supported flag values, see
| the LOAD_LIBRARY_SEARCH_* entries in LoadLibraryEx.
...
| [...] if you specify the link option /DEPENDENTLOADFLAG:0x800
| (the value of the flag LOAD_LIBRARY_SEARCH_SYSTEM32), then the
| module search path is limited to the %windows%\system32 directory.


The changed documentation is but STILL wrong, /DEPENDENTLOADFLAG
also FAILS to restrict the DLL search path for LOADTIME linking.

JFTR: for the definitions of RUNTIME linking and LOADTIME linking,
see <https://msdn.microsoft.com/en-us/library/ms685090.aspx>
and <https://msdn.microsoft.com/en-us/library/ms684184.aspx>


Demonstration (continued):
~~~~~~~~~~~~~~~~~~~~~~~~~~

5. build another minimal application SNAFU.EXE from the following
source file SNAFU.C

__declspec(dllimport)
extern BOOL WINAPI _DllMainCRTStartup(HANDLE hModule, DWORD dwReason, LPVOID lpReserved);

__declspec(noreturn)
VOID WINAPI mainCRTStartup(VOID)
{
ExitProcess(_DllMainCRTStartup != NULL);
}

with the following command:

CL.EXE SNAFU.C SNAFU.LIB /link /DEFAULTLIB:kernel32.lib /ENTRY:mainCRTStartup

6. run the second application SNAFU.EXE and display its exit code
with the following commands:

.\SNAFU.EXE
Echo %ERRORLEVEL%

The exit code is 0, proving that /DEPENDENTLOADFLAG:... does
NOT limit the DLL search path for Windows' module loader!

7. When you change the return value of the DLL's entry point
function _DllMainCRTStartup() to FALSE, Windows module loader
shows a message box and the exit code is 0xC0000142 alias
STATUS_DLL_INIT_FAILED, again proving that
/DEPENDENTLOADFLAG:0x800 does NOT work as documented!

8. When you erase SNAFU.DLL and run SNAFU.EXE, Windows module
loader shows a message box and the exit code is 0xC0000135
alias STATUS_DLL_NOT_FOUND, which is the expected behaviour
if /DEPENDENTLOADFLAG:0x800 would work as documented and limit
the DLL search path to %SystemRoot%\System32\


stay tuned, and don't trust unverified or incomplete documentation
Stefan Kanthak

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close