关于COM口{A6BFEA43-501F-456F-A845-983D3AD7B8F0} BypassUAC研究

  1. 前言
  2. 参考链接
  3. 模仿复刻
  4. 其他

前言

今天上线的机器,通过用DLL劫持和注册表进行BypassUac发现很不行。win10下的360可能不杀可能杀,注册表通过修改ShellCommand来实现ByPassUAC的操作。过于敏感,而DLL劫持BypassUAC用久后又会被杀。今天翻文章看到头像哥的COM口bypassuac。发现可行,稍微研究了一下

参考链接

https://www.zcgonvh.com/post/Advanced_Windows_Task_Scheduler_Playbook-Part.2_from_COM_to_UAC_bypass_and_get_SYSTEM_dirtectly.html
https://3gstudent.github.io/backup-3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%9F%BA%E7%A1%80-Windows%E4%B8%8B%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1%E7%9A%84%E4%BD%BF%E7%94%A8/
https://3gstudent.github.io/%E9%80%9A%E8%BF%87COM%E7%BB%84%E4%BB%B6NetFwPolicy2%E8%B6%8A%E6%9D%83%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99
https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-dllgetclassobject
http://www.cppblog.com/Streamlet/archive/2012/09/07/189762.html

Github Link:https://github.com/zcgonvh/TaskSchedulerMisc/blob/master/schuac.cs

模仿复刻

COM Elevation Moniker的使用对COM组件有如下要求
该COM组件被注册
注册位置在HKEY_LOCAL_MACHINE下,也就是说,需要以管理员权限注册这个COM组件才可以
注册表HKEY_LOCAL_MACHINE\Software\Classes\CLSID下需要指定三项键值{CLSID}, LocalizedString(REG_EXPAND_SZ):displayName
{CLSID}/Elevation,IconReference(REG_EXPAND_SZ):applicationIcon
{CLSID}/Elevation,Enabled(REG_DWORD):1

Elevation项 - Enabled判断是否启用
InProcServer32 - 一个 32 位进程内服务器并指定服务器可以运行的单元的线程模型
VirtualServerObjects - 辅助对象(在微软的文档里,我没找到描述这个的内容)->我理解为COM口CLSID有这个项的,理解为子COM口
ProgID - 系统服务名称
Programmable - 可编程的
TypeLib -
Version - 版本

通过查询:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}可以得到如下

PS C:\Users\Lenovo> reg query "HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}"
HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}
    (默认)    REG_SZ    Virtual Factory for MaintenanceUI
    AppId    REG_SZ    {A6BFEA43-501F-456F-A845-983D3AD7B8F0}
    LocalizedString    REG_EXPAND_SZ    @%SystemRoot%\System32\MaintenanceUI.dll,-1


HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\Elevation
HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\InProcServer32
HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\VirtualServerObjects

PS C:\Users\Lenovo> reg query "HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\VirtualServerObjects"
HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\VirtualServerObjects
    {0f87369f-a4e5-4cfc-bd3e-73e6154572dd}    REG_SZ



PS C:\Users\Lenovo> reg query "HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\Elevation"
HKEY_CLASSES_ROOT\CLSID\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}\Elevation
    Enabled    REG_DWORD    0x1

此时我们可以得到的信息有

COM Name:Virtual Factory for MaintenanceUI
COM GUID:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}
处理该COM的文件:@%SystemRoot%\System32\MaintenanceUI.dll
子COM口:{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}
COM口是否启用:0x1

此时我们要研究的COM口的SID是:{0f87369f-a4e5-4cfc-bd3e-73e6154572dd},通过注册表查询并没有见到Elevation,意味着我们不能直接调用这个COM口

powershell连接如下

$obj =[activator]::CreateInstance([type]::GetTypeFromCLSID("A6BFEA43-501F-456F-A845-983D3AD7B8F0"))
$obj | get-member

而A6BFEA43-501F-456F-A845-983D3AD7B8F0

根据头像哥的文章进行复现

https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-dllgetclassobject

调用operator new分配足够的空间,并调用相关对象的构造函数
调用CClassFactory工厂类

大概是::CreateInstance

CClassFactory::CreateInstance

上面的两个if判断相加后是否等于对应的GUID
如果两个都不是则去到30行

*a4 = 0i64;
  v4 = (const struct _GUID *)((char *)this + 8);
  v5 = a4;
  v6 = a3;
  if ( *(_OWORD *)((char *)this + 8) == *(_OWORD *)&CLSID_MultiObjectElevationFactory ) //-> CLSID:36F0BD14-0D84D-468C-0B79C99900F30FA897F
  {
    if ( WPP_GLOBAL_Control != &WPP_GLOBAL_Control && *((_BYTE *)WPP_GLOBAL_Control + 28) & 8 )
      WPP_SF_(*((_QWORD *)WPP_GLOBAL_Control + 2), 12i64, &WPP_8681af7930fc3f9ff14ce17035134427_Traceguids);
    v7 = CElevatedFactoryClient::CreateInstance(v6, v5);
LABEL_16:
    v9 = v7;
    goto LABEL_21;
  }
  if ( *(_OWORD *)((char *)this + 8) == *(_OWORD *)&CLSID_ElevatedFactoryServerManager ) -> CLSID:0E755468C-2F5-4D96-84873B0E68F0FE633A
  {
    if ( WPP_GLOBAL_Control != &WPP_GLOBAL_Control && *((_BYTE *)WPP_GLOBAL_Control + 28) & 8 )
      WPP_SF_(*((_QWORD *)WPP_GLOBAL_Control + 2), 13i64, &WPP_8681af7930fc3f9ff14ce17035134427_Traceguids);
    v7 = CElevatedFactoryServerManager::GetSingleton(v6, v5);
    goto LABEL_16;
  }

 v8 = _IsValidVirtualFactory(v4);
  v9 = v8;
  if ( !v8 )
  {
    if ( WPP_GLOBAL_Control != &WPP_GLOBAL_Control && *((_BYTE *)WPP_GLOBAL_Control + 28) & 8 )
      WPP_SF_(*((_QWORD *)WPP_GLOBAL_Control + 2), 14i64, &WPP_8681af7930fc3f9ff14ce17035134427_Traceguids);
    v7 = CElevatedFactoryServer::CreateInstance(v4, v6, v5);
    goto LABEL_16;
  }

CElevatedFactoryServer::CreateInstance
返回CElevatedFactoryServer实例

通过查看发现只有一个接口


创建并默认初始化与指定 CLSID 关联的类的单个对象。当您只想在本地系统上创建一个对象时,请调用CoCreateInstance 。要在远程系统上创建单个对象,请调用CoCreateInstanceEx函数。要基于单个 CLSID 创建多个对象,请调用CoGetClassObject函数。

HRESULT CoCreateInstance(
  [in]  REFCLSID  rclsid,
  [in]  LPUNKNOWN pUnkOuter,
  [in]  DWORD     dwClsContext,
  [in]  REFIID    riid,
  [out] LPVOID    *ppv
);

https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance

获取接口类对应的CLSID

(每个接口类都有一个CLSID)

回到开头判断CLSID那个地方跟踪上一个CLSID即可发现(赌- -)

正确寻找该CLSID的方法应该是定位到对应工厂类的QueryInterface函数调用该变量

至此结论是:
由于CElevatedFactoryServer::ServerCreateElevatedObject首个参数可控,利用该参数可以创建任意注册路径表带有VirtualServerObjects项的CLSD对象

然后选择能利用的COM口,这里的0f87369f-a4e5-4cfc-bd3e-73e6154572dd就是用来操控计划任务的。然后只需要找到对应调用的接口类,声明对应的接口类并调用其中类的里的某个函数。
例如代码里的:ITaskService

其他

其他知识点(抄自头像哥)

我们知道经过UAC提升的COM对象需要使用`CoGetObject`函数,结合`Elevation Moniker`进行激活,这个行为记录在https://docs.microsoft.com/en-us/windows/win32/com/the-com-elevation-moniker。
参考文章代码,我们注意到在微软的示例中采用`CLSCTX_LOCAL_SERVER`作为激活上下文标记,这表示要求DCOMLaunch创建一个新的进程外COM对象,`A6BFEA43-501F-456F-A845-983D3AD7B8F0`对象仅配置了`InProcServer32`,这将导致`代理激活(Surrogate Activation)`。
关于代理激活有两个重要的点:首先从安全研究角度,配置了`APPID`的代理激活往往存在自定义权限检查。
参考文档https://docs.microsoft.com/en-us/windows/win32/com/launchpermission与https://docs.microsoft.com/en-us/windows/win32/com/accesspermission,默认隐式权限检查由注册表项`HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{APPID}@LaunchPermission`、`HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{APPID}@AccessPermission`共同决定,其值为二进制格式表示的安全描述符`Security Descriptor(SD) binary form`。

$x=get-itemproperty 'hklm:\software\classes\appid\{A6BFEA43-501F-456F-A845-983D3AD7B8F0}'
(new-object System.Security.AccessControl.RawSecurityDescriptor($x.LaunchPermission,0)).DiscretionaryAcl|fl
(new-object System.Security.AccessControl.RawSecurityDescriptor($x.AccessPermission,0)).DiscretionaryAcl|fl

注意:该CLSID win7以上才有(Windows Server 2012开始有)


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:关于COM口{A6BFEA43-501F-456F-A845-983D3AD7B8F0} BypassUAC研究

本文作者:九世

发布时间:2023-07-20, 00:11:12

最后更新:2023-07-20, 00:41:11

原始链接:http://jiushill.github.io/posts/bf1048f6.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录