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:

November 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close