BypassUAC

BypassUAC

本篇主要介绍如何以ICMLuaUtil方式BypassUAC,主要内容如下:

  • 过掉UAC提示框的方法总结
  • UACME项目
  • 什么类型的COM interface可以利用?
  • 如何快速找到系统中的所有可利用的COM组件?
  • 定位ICMLuaUtil的虚函数表vftable
  • 如何调用ICMLuaUtil.ShellExec执行命令?
    • C++ version
    • CSharp version
      • 两个注意点
  • DLL形式
    • C++ dll导出函数方式
    • C# dll导出函数方式
      • 一个坑
  • 值得研究的C2推荐

过掉UAC提示框的方法总结

这里主要说的是dll的形式,通过上面的实操,可以发现有两种方法:

  • 基于白名单程序绕过UAC
  • 伪装进程PEB绕过UAC
  • 无文件技术

伪装进程的方式其实也可以算做借助了白名单,但是没有直接调用白名单进程,所以单独列出来了。

基于白名单程序绕过UAC

有些系统程序是直接获取管理员权限,而不会触发UAC弹框,这类程序称为白名单程序,例如:slui.exewusa.exetaskmgr.exemsra.exeeudcedit.exeeventvwr.exeCompMgmtLauncher.exerundll32.exeexplorer.exe等等。

常见的利用方式有:

  • DLL注入(RDI技术),一般注入到常驻内存的可信进程,如:explorer
  • DLL劫持,常和注册表配合使用达到劫持目的

伪装进程PEB绕过UAC

上面在利用COM接口的ShellExec执行命令的时候,因为执行该操作的进程身份是不可信的,所以会触发UAC弹窗。为了能够迷惑系统,通过修改PEB结构,让系统误认为这是一个可信进程,伪装的可信进程可以是calc.exerundll32.exeexplorer.exe等。

利用火绒剑查看进程信息,可以看到已经识别为可信进程了:

关于PEB的结构,可以参照这里

无文件技术

“无文件攻击”是一种攻击策略,其出发点就是避免将恶意文件放在磁盘上,以逃避安全检测。无文件四种攻击形式:

  1. 恶意文档 比如:在word中加入恶意的宏代码实现命令执行,又或者邮件中。
  2. 恶意脚本 常用的脚本引擎:powershell.exe,cscript.exe,cmd.exe 和 mshta.exe,同样不生成恶意二进制文件。
  3. 恶意本地程序交互 例如:rundll32.exewmi等,详细参考这里
  4. 恶意内存代码 直接生成纯shellcode,通过其他方式加载到内存执行。

UACME项目

项目地址:https://github.com/hfiref0x/UACME

项目总结了50多种绕过UAC的方式,并且列出具备auto-elevate能力的UAC白名单程序或接口。

利用方式主要可以分为两大类:

  1. 各类UAC白名单程序的DLL劫持(Dll Hijack
  2. 各类提升权限的COM接口利用(Elevated COM interface

项目的主程序为Akagi,其中包含了所有的method,使用vs2019本地编译后可以使用akagi32 41或者akagi64 41启动程序,41这个指的是README中描述的方法索引,运行后可以直接得到管理员权限的cmd窗口。

项目的Source目录存储的是所有子项目的源码,其中Source/Shared存放的是被所有子项目共同引用的一些函数,本篇主要利用AkagiYuubari这两个Project来探究一下如何利用COM接口提升权限。

什么类型的COM interface可以利用?

以项目中索引为41的方法为例:

Author: Oddvar Moe
Type: Elevated COM interface
Method: ICMLuaUtil
Target(s): Attacker defined
Component(s): Attacker defined
Implementation: ucmCMLuaUtilShellExecMethod
Works from: Windows 7 (7600)
Fixed in: unfixed ?
How: -

该方法的目标接口是ICMLuaUtil,对应Akagi项目中具体实现函数为ucmCMLuaUtilShellExecMethod,在项目中的methods/api0cradle.c文件中可以找到该方法的定义:

观察发现这里利用的是CMSTPLUA组件的ICMLuaUtil接口。

我的测试系统Windows 10 (1909),使用OleViewDotNet工具可以查看系统中的COM接口属性信息,注意需要以管理员权限运行。

打开CLSIDs窗口搜索cmstplua,可以快速定位该组件:

右键查看CMSTPLUA组件的Elevation属性:

这里的EnabledAuto Approval值都是True表示这个组件可以用来绕过UAC认证,这是第一点。

第二点是目标接口ICMLuaUtil需要有一个可以执行命令的地方,通过在CISIDs窗口鼠标悬浮在ICMLuaUtil上,可以看到该接口对应的二进制文件为cmlua.dll

虚函数偏移为cmlua.dll+0x6360,通过IDA打开该系统文件(c:\windows\system32\cmlua.dll),跳到虚函数表的位置,可以看到ICMLuaUtil接口的虚函数表:

摘出来看接口函数如下:

01 QueryInterface(_GUID const &,void * *)
02 AddRef(void)
03 Release(void)
04 SetRasCredentials(ushort const *,ushort const *,ushort const *,int)
05 SetRasEntryProperties(ushort const *,ushort const *,ushort * *,ulong)
06 DeleteRasEntry(ushort const *,ushort const *)
07 LaunchInfSection(ushort const *,ushort const *,ushort const *,int)
08 LaunchInfSectionEx(ushort const *,ushort const *,ulong)
09 CreateLayerDirectory(ushort const *)
10 ShellExec(ushort const *,ushort const *,ushort const *,ulong,ulong)
11 SetRegistryStringValue(int,ushort const *,ushort const *,ushort const *)
12 DeleteRegistryStringValue(int,ushort const *,ushort const *)
13 DeleteRegKeysWithoutSubKeys(int,ushort const *,int)
14 DeleteRegTree(int,ushort const *)
15 ExitWindowsFunc(void)
16 AllowAccessToTheWorld(ushort const *)
17 CreateFileAndClose(ushort const *,ulong,ulong,ulong,ulong)
18 DeleteHiddenCmProfileFiles(ushort const *)
19 CallCustomActionDll(ushort const *,ushort const *,ushort const *,ushort const *,ulong *)
20 RunCustomActionExe(ushort const *,ushort const *,ushort * *)
21 SetRasSubEntryProperties(ushort const *,ushort const *,ulong,ushort * *,ulong)
22 DeleteRasSubEntry(ushort const *,ushort const *,ulong)
23 SetCustomAuthData(ushort const *,ushort const *,ushort const *,ulong)

其中第10个函数ShellExecIDA中看到该函数调用了ShellExecuteEx这个Windows API实现了命令执行:

通过对ICMLuaUtil接口的分析,可以看出可以用来BypassUAC执行命令的COM组件需要有两个特点:

  1. elevation属性启用,且开启Auto Approval
  2. COM组件中的接口存在可以命令执行的地方,例如ICMLuaUtilShellExec

如何快速找到系统中的所有可利用的COM组件?

除了通过上面的方式在OleView中手动去找,还可以通过UACMe项目提供的Yuubari工具快速查看系统UAC设定信息以及所有可以利用的程序和COM组件,使用方法如下:

使用VS2019加载Yuubari,生成后会得到二进制文件UacInfo64.exe,运行后在同目录生成一个log文件记录所有输出结果:

从这里面可以找到所有的Autoelevated COM objects,包括CMSTPLUA组件的信息:

定位ICMLuaUtil的虚函数表vftable

通过分析UACMe中的ucmCMLuaUtilShellExecMethod实现可以知道想要利用COM接口,需要知道这几个东西:

  • 标识COM组件的GUID,即CLSID
  • 标识interfaceGUID,即IID
  • 该接口的虚函数表,主要用来找到ShellExec的函数偏移

前两个可以很容易找到,虚函数表可以通过OleView提示的虚函数表位置偏移找到,这里再说一种通用的方法,完全利用IDA

第一步,用IDA打开cmlua.dll; 第二步,在左侧函数列表中搜索destructor或者constructor,双击后跳转后,上下找找可以看到调用vftable的地方:

双击跳转到变量定义位置,就可以找到虚函数表!

参考:Get interface definition of undocumented COM objects

如何调用ICMLuaUtil.ShellExec执行命令?

c++ version

代码是从UACMe中摘出来的,放在了github上。

代码地址:BypassUAC

如果直接把ucmCMLuaUtilShellExecMethod这个函数直接摘出来,会发现还是会弹UAC的窗:

vs2019中可以对Akagi项目调试,项目属性中设置命令参数为41

直接在函数ucmCMLuaUtilShellExecMethod的地方下断:

通过分析函数调用链,发现ucmMain在调用对应方法之前先调用了supMasquradeProcess这个函数。

该函数负责进行PEB的伪装,将自己的进程信息伪装成为c:\windows\explorer.exe这个系统的可信进程,这样才能绕过UAC认证窗口,所以在使用COM组件提权之前需要先伪装一下进程才可以:

这种方式,因为修改的是自己的进程信息,并不是修改其他进程,所以一般杀软、AV是不会拦的。

CSharp version

代码摘自Moriarty2016p0wnedShell

代码地址:BypassUAC_csharp

两个注意点

C#版本的代码中需要注意ICMLuaUtil接口的定义,其继承自IUnKnown,该接口定义函数如下:

IUnknown::AddRef
IUnknown::QueryInterface
IUnknown::QueryInterface

所以在定义ICMLuaUtil的时候,有以下两点需要注意:

  1. 指明继承自IUnKnown接口;
  2. 继承的函数不需要加上,C#会自动添加;

关于C#接口的知识,可以从这里了解更多。

DLL 形式

如何使用?

dll可以使用系统可信进程rundll32.exe进行加载,这样也不需要调用MarquradePEB

C++ dll导出函数的方式

代码地址:BypassUAC_Dll

导出的函数为BypassUAC,导出方式直接新建一个def文件,格式参考这里,内容如下:

LIBRARY	BypassUAC
EXPORTS
	BypassUAC

生成之后通过CFF Explorer查看导出表:

利用rundll32.exe .\BypassUAC_Dll.dll,BypassUAC命令测试后,bypass成功!

C# 导出dll函数的方式

代码地址:BypassUAC_Dll_csharp

C#导出dll函数的方式有两种:

  1. 使用DllExport这个NuGet
  2. 通过IL反编译的方式

DllExport

默认C#导入其他库函数,可以使用[DllImport],但是不支持[DllExport],通过NuGet包管理器安装DllExport这个包可以实现这个功能。

vs中可以对指定项目安装这个包:

安装之后,直接使用[DllExport]导出BypassUAC函数即可:

重新生成dll文件,在CFF中查看,已经导出成功:

IL 反编译

如果了解Java的,java文件首先编译成class,然后交给JVM去解释成机器码。.net为了跨平台,这里类似,同样有一个中间语言的文件,但不是class了,而是IL

通过修改IL文件,也可以导出dll函数。

首先去除[DllExport]后将dll代码编译,编译后的dll文件是看不到Export Directory的。

然后ildasmdll文件反编译成il文件,命令如下:

ildasm BypassUAC_Dll_csharp.dll /out=BypassUAC_Dll_csharp.il

打开生成的BypassUAC_Dll_csharp.il文件,找到需要导出的目标函数BypassUAC,在函数开头处添加如下代码:

.export [1]

保存后,需要使用ilasm再把il编译成dll文件,这里遇到一个坑,如果按照如下命令进行编译:

ilasm BypassUAC_Dll_csharp.il /dll /out=BypassUAC_Dll_csharp_exp.dll

发现使用rundll32.exe .\BypassUAC_Dll_csharp_exp.dll,BypassUAC运行后没有任何反应。

BypassUAC函数开头处添加一个MessageBox弹窗,再次运行弹框之后,附加到windbg调试,让程序再次跑起来,运行结束后在windbg中可以看到:

进程加载的cmlua.dll文件并不是system32目录,而是SysWOW64的,SysWOW64放的是32位系统文件,程序为什么去加载的是32位的,使用CFF看一下生成的dll文件类型:

问题的根源就是这里,利用IL转之前的dll64位的,转之后变成了32位的,解决方法很简单,使用ilasm的时候添加一个/X64参数就可以了:

ilasm BypassUAC_Dll_csharp.il /dll /X64 /out=BypassUAC_Dll_csharp_exp.dll

这样就可以成功的BypassUAC了。

值得研究的C2推荐

  • Python
    • Empire,官方已经不维护了不推荐用,但是值得研究借鉴
    • Pupy,很适合玩Python的研究
    • SILENTTRINITY,利用的.net DLR方式实现,动态加载不落地
    • PoshC2
  • .NET

其他参考

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Ajax数据的爬取(淘女郎为例)

    如果使用的是 Chrome 的话,可以首先选中 XHR 来更快速的找出获取数据的 API,如果在 XHR 里面没有再去 JS 里面一个个的寻找。

    CN_Simo
  • [JavaScript]自执行函数

    最近在接触mui的时候,遇到了一段代码: 1 (function($, doc) { 2 $.init({ 3 ...

    CN_Simo
  • c++错误代码1

    今天敲c++,出现一个错误,这个题目错误代码如下: ? 并没有提示有错误而终止。 运行结果却错了: ? 很明显,错误的地方是变量r没有初始化。 这让我知道了,这...

    CN_Simo
  • 基于深度学习的图像超分辨率最新进展与趋势【附PDF】

    图像超分辨率是计算机视觉和图像处理领域一个非常重要的研究问题,在医疗图像分析、生物特征识别、视频监控与安全等实际场景中有着广泛的应用。随着深度学习技术的发展,基...

    马上科普尚尚
  • 前端小知识11点

    参考:页面显示LCD液晶字体,特殊字体,@font-face属性详细用法(https://blog.csdn.net/sunshine_han/article/...

    进击的小进进
  • 使用Python+tkinter编写电脑桌面放大镜程序

    代码思路:首先全屏截图,然后在鼠标当前位置以小窗口进行二次截图,放大后再显示到鼠标左上角。 主要技术:全屏截图,指定区域截图,绑定鼠标事件,绘制图像。 ? 建议...

    Python小屋屋主
  • C++之const

    程序手艺人
  • Java实现文件复制的四种方式

    背景:有很多的Java初学者对于文件复制的操作总是搞不懂,下面我将用4中方式实现指定文件的复制。

    阿豪聊干货
  • logback 配置

    (adsbygoogle = window.adsbygoogle || []).push({});

    yawn
  • 可视化系统搭建--遇见大数据可视化系列文章之四

    腾讯ISUX

扫码关注云+社区

领取腾讯云代金券