关于COM口{A6BFEA43-501F-456F-A845-983D3AD7B8F0} BypassUAC研究
前言
今天上线的机器,通过用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工厂类
大概是
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" 转载请保留原文链接及作者。