March 22

Redirect with spoofing. We are looking for loopholes in Windows for the execution of third-party code

Inside Windows lies a huge number of interesting and unobvious possibilities. In this article I will show you how to force the operating system to load our library into any process!

One of the most popular privilege escalation attacks is DLL Hijacking. To carry it out, the attacker places his malicious library in the search path of a legitimate DLL. This leads to the target application loading a third-party lib and executing malicious code.

At first glance, this attack seems very simple. I would even say primitive. However, there are several pitfalls that attackers often overlook.

Firstly, many people forget to do DLL Proxying to the target library, which leads to the breakdown of the entire application. It crashes because it tries to call a function from a library that does not contain the required code.

Secondly, sometimes calls to functions like LoadLibrary(), CreateProcess() and CreateThread() are placed in the DllMain() function, which leads to Dead Lock due to the Loader Lock mechanism. Loader Lock acts as a critical section (process thread synchronization primitive). In fact, the execution of the program thread is blocked until the Loader Lock is removed.

WWW

Read more in the blog: Perfect DLL Hijacking, What is Loader Lock.

Third, there are some factors that affect the order in which DLLs are searched. Standard search paths are shown below.

Where does Windows look for DLLs?

This is the so-called SafeDllSearchOrder. If it is disabled, then after the Application Directory the LoadLibrary*() function looks at the Current Directory. You can disable SafeDllSearchMode by setting the value to zero along this path:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode 

Another factor that affects search is the LoadLibraryEx() function called with the value LOAD_WITH_ALTERED_SEARCH_PATH. In this case, the first thing to do is look for the DLLs along the path specified inside this function.

Among other things, there are built-in Windows mechanisms that allow you to embed our library into the target process. Microsoft documentation mentions some of them. Let's study them in more detail.

DLL REDIRECTION

For regular executable files

DLL Redirection is a special mechanism that allows programs to use different versions of a DLL for their tasks, without affecting regular system libraries. The effect applies only to the LoadLibrary*() functions.

In fact, regardless of whether it contains the full path (C:\Windows\System32\dll.dll) or the short one (dll.dll), the function will check whether it is present in the current directory (which contains the application that called this function ) file with the extension .local. And if present, then the LoadLibrary*() function will in any case load first the DLL from the current application directory.

The name of the .local file must be the same as the name of the process from which the LoadLibrary() function was called. For example, if the application is Editor.exe, then the file name should be Editor.exe.local.

Let’s imagine that this same C:\myapp\Editor.exe will try to load some lib via LoadLibrary*(). For example, like this:

C:\Program Files\Common Files\System\mydll.dll

Then LoadLibrary*() will check for the existence of the Editor.exe.local file in the directory where Editor.exe is located. If the .local file is found, the function will first try to load mydll.dll from the current directory.

That is, this path is checked first:

C:\myapp\mydll.dll

And if there is no such file, it will be downloaded from the specified full path:

C:\Program Files\Common Files\System\mydll.dll

The most interesting thing: we can create not only the Editor.exe.local file, but also a folder with the same name, because the contents of the .local file are not checked. In this case, the DLL will be loaded in the following path:

C:\myapp\myapp.exe.local\mydll.dll

So, let's start writing the PoC. First, we need a target application that will load the library with the full path.

Let's call this application Article.exe.

#include <Windows.h>#include <iostream>int main() { LoadLibraryW(L"C:\\Users\\Michael\\Desktop\\Redir.dll"); char a; std::cin >> a; return 0;}

В качес­тве легитим­ной биб­лиоте­ки ском­пилиру­ем сле­дующий код и назовем Redir.dll.

#include "pch.h"BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBox(NULL, L"HI FROM LEGIT", L"HI FROM LEGIT", MB_OK); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}

After compilation, move the Redir.dll library to the C:\Users\Michael\Desktop folder. Let's check that it starts and runs successfully.

Successful loading of a legitimate library
Correct way " suiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii "

Now change the Redir.dll code to the following.

#include "pch.h"BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBox(NULL, L"HI FROM FAKE", L"HI FROM FAKE", MB_OK); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}

Let's compile it and create the Article.exe.local file in the folder with Article.exe.

Enabling Dll Redirection

Now let's run the executable file and make sure that the library is actually loaded from the current application directory, and not from the full path.

Successful operation of DLL Redirection
Make sure the required library is loaded

If you delete the .local file, the required library will be loaded again.

Loading a legitimate library

.NET Assemblies

For .NET assemblies, everything is a little simpler. We need to create a .manifest file, or edit an existing one, adding a dependency on a specific library to it. Here is an example configuration file.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentityversion="6.0.0.0"processorArchitecture="x86"name="redirector"type="win32"/><description>DLL Redirection</description><dependency><dependentAssembly><assemblyIdentitytype="win32"name="Microsoft.Windows.Common-Controls"version="6.0.0.0"processorArchitecture="X86"publicKeyToken="6595b64144ccf1df"language="*"/></dependentAssembly></dependency> <file name="user32.dll" /></assembly>

In this case, we use the name attribute to indicate that the target assembly depends on user32.dll. After that, the file must be saved with the name program.exe.manifest, where program.exe is the name of the application into which the library should be loaded.

This will cause user32.dll to be loaded from the directory where the application is launched.

IMAGE PATH NAME SPOOFING suiiiiiii

Theory

The attack is that we can use Rtl* functions and trick the application into thinking that it is running from a different directory. Figuratively, the application is located in C:\Windows\System32\abc.exe, and we will say that in C:\Users\abc.exe . As a consequence, abc.exe will load libraries from C:\Users.

Everything is based on the RtlCreateProcessParametersEx() and RtlCreateUserProcess() functions. Windows (as well as the CLR platform) will look for libraries (or .NET assemblies, in the case of the CLR) along the path specified in the ImagePathName element of the RTL_USER_PROCESS_PARAMETERS structure. This structure is generated by the RtlCreateProcessParametersEx() function. The running process will, in turn, parse this structure and extract the ImagePathName from it. And, as a result, it will reveal the current directory, which is actually spoofed.