lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <4698C56621434055B4882D4B1652CD24@W340>
Date: Tue, 6 Sep 2016 23:19:14 +0200
From: "Stefan Kanthak" <stefan.kanthak@...go.de>
To: <bugtraq@...urityfocus.com>
Cc: fulldisclosure@...lists.org
Subject: [FD] Defense in depth -- the Microsoft way (part 43): restricting
	the DLL load order fails

Hi @ll,

according to <https://msdn.microsoft.com/en-us/library/ms684179.aspx>
and <https://msdn.microsoft.com/en-us/library/ms682586.aspx>,
LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH should NOT search
the calling program's application directory:

| Note that the standard search strategy and the alternate search
| strategy specified by LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH
| differ in just one way: The standard search begins in the calling
| application's directory, and the alternate search begins in the
| directory of the executable module that LoadLibraryEx is loading.
|
| If SafeDllSearchMode is enabled, the alternate search order is as
| follows:
| 1. The directory specified by lpFileName.
| 2. The system directory. Use the GetSystemDirectory function to get
|    the path of this directory.
| 3. The 16-bit system directory. There is no function that obtains the
|    path of this directory, but it is searched.
| 4. The Windows directory. Use the GetWindowsDirectory function to get
|    the path of this directory.
| 5. The current directory.
| 6. The directories that are listed in the PATH environment variable.
|    Note that this does not include the per-application path specified
|    by the App Paths registry key. The App Paths key is not used when
|    computing the DLL search path.
|
| If SafeDllSearchMode is disabled, the alternate search order is as
| follows:
| 1. The directory specified by lpFileName.
| 2. The current directory.
| 3. The system directory. Use the GetSystemDirectory function to get
|    the path of this directory.
| 4. The 16-bit system directory. There is no function that obtains the
|    path of this directory, but it is searched.
| 5. The Windows directory. Use the GetWindowsDirectory function to get
|    the path of this directory.
| 6. The directories that are listed in the PATH environment variable.
|    Note that this does not include the per-application path specified
|    by the App Paths registry key. The App Paths key is not used when
|    computing the DLL search path.


On a fully patched Windows 7 SP1 (I've not tested on other versions), the
following program but loads VERSION.DLL from its application directory:

--- POC.C ---
#pragma comment(lib, "KERNEL32.LIB")

#pragma comment(linker, "/ENTRY:WinMainCRTStartup")
#pragma comment(linker, "/SUBSYSTEM:Windows")

#include <windows.h>

void WinMainCRTStartup()
{
    HMODULE hModule = LoadLibraryEx("C:\\Program Files\\Common Files\\System\\WAB32.DLL",
                                    NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    if (hModule == NULL)
        ExitProcess(GetLastError());

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

    ExitProcess(ERROR_SUCCESS);
}
--- EOF ---

VERSION.DLL is (via the API sets introduced in Windows 7) an INDIRECT
load-time dependency of (not only) WAB32.DLL.

This bug allows to exploit a well-known and well-documented weakness:
see <https://cwe.mitre.org/data/definitions/426.html>,
<https://cwe.mitre.org/data/definitions/427.html> and
<https://capec.mitre.org/data/definitions/471.html>


Mitigations:
~~~~~~~~~~~~

* add VERSION.DLL to the "known DLLs":

  [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs]
  "Version"="Version.Dll"

* embed the following "application manifest" in your executables:

  <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  <assembly manifestVersion="1.0"
            xmlns="urn:schemas-microsoft-com:asm.v1">
      <file name="Version.dll"
            loadFrom="%SystemRoot%\System32\Version.dll" />
  </assembly>

  CAVEAT: the loadFrom attribute of the file element is not documented!


stay tuned
Stefan Kanthak


Timeline:
~~~~~~~~~

2016-09-03    report sent to vendor

2016-09-06    vendor replies:
              "Upon investigation we have determined that this does
               not meet the bar for security servicing at this time."

2016-09-06    report published

_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ