远离远程代码执行 ,RPC 运行时中的三个漏洞是如何被发现的?
引言
MS-RPC 是 Windows 网络中广泛使用的协议,许多服务和应用程序都依赖它。 因此,MS-RPC 中的漏洞可能会导致严重后果。 Akamai 安全情报小组在过去一年中一直致力于 MS-RPC 研究。 我们发现并利用了漏洞,构建了研究工具,并编写了协议的一些未记录的内部结构。
Akamai 研究员 Ben Barnea 在 Microsoft Windows RPC 运行时中发现了三个重要漏洞,这些漏洞的基本评分均为 8.1:CVE-2023-24869、CVE-2023-24908 和 CVE-2023-23405。这些漏洞可能导致远程代码执行。由于 RPC 运行时库已加载到所有 RPC 服务器中,并且这些服务器通常由 Windows 服务使用,因此所有 Windows 版本(桌面版和服务器版)都会受到影响。产生这些漏洞的原因是 RPC 运行时使用的三种数据结构中的整数溢出。目前 Akamai 已负责任地向 Microsoft 披露这些漏洞,并且这些漏洞于 2023 年 3 月的补丁星期二得到解决。
虽然之前的一些文章主要关注服务中的漏洞,但我们将在本篇文章中探讨 RPC 运行时(MS-RPC 的 “引擎”)中的漏洞。这些漏洞与我们在 2022 年 5 月发现的漏洞类似。
整数溢出模式
这三个新漏洞有一个共同的主题 —— 它们都是由于插入三个数据结构时出现整数溢出而存在的:
- SIMPLE_DICT(只保存值的字典)
- SIMPLE_DICT2(同时保存键和值的字典)
- 队列
所有这些数据结构都是使用动态数组实现的,每次数组变满时该数组都会增长。 这是通过分配为当前数组分配的内存的两倍来实现的。 此分配容易受到整数溢出的影响。
图 1 显示了 RPC 运行时的反编译代码。它显示了 SIMPLE_DICT 结构的插入过程以及可以触发整数溢出的易受攻击的代码行(高亮显示)。

图 1:SIMPLE_DICT 结构扩展中的整数溢出
探索产生漏洞的原因
要触发漏洞,我们需要了解其根本原因,弄清楚是否存在指向漏洞函数的流程,以及触发需要多长时间。
为了简洁起见,我们将描述这三个漏洞之一:队列数据结构中的漏洞。由于其他整数溢出本质上是相似的,因此以下各节中进行的分析可以互换进行。
了解整数溢出
队列是一种简单的 FIFO(先进先出)数据结构。 RPC 运行时中的队列是使用一个结构体实现的,该结构体包含队列条目数组、当前容量以及队列中最后一项的位置。
当一个新条目添加到队列中时(假设有一个可用槽),所有项目都会在数组中向前移动,并且新项目将添加到数组的开头。 然后队列中最后一项的位置递增。
当发生出列时,最后一个项目将被拉出,并且最后一个项目的位置会递减(如图 2 所示)

图 2:排队和出队操作期间的队列结构
如前所述,该漏洞发生在插入新条目时。 如果动态数组已满,代码将执行以下操作:
- 分配具有以下大小的新数组:
当前容量 * 2 * sizeof (QueueEntry) - 将旧项目复制到新数组
- 释放旧项目数组
- 容量加倍
对于 32 位系统,在计算新数组大小时会发生溢出:
- 我们用 0x10000000 (!) 个项目填充队列。
- 发生扩展。新分配的大小计算为:0x10000000 * 16。由于溢出,新分配大小为 0。
- 分配了一个零长度数组。
- 代码将旧的 items 数组复制到新的小数组中。这将导致野生副本(线性大副本)。
在 64 位系统上,该漏洞无法被利用,因为会有大量的分配失败。这会导致代码正常退出,因而不会触发任何越界写入。尽管 64 位系统不会受到此问题的影响,但它们仍然很容易受到其他整数溢出的影响(在 SIMPLE_DICT 和 SIMPLE_DICT2 中)。
代码流
RPC 连接使用 OSF_CONNECTION 类表示。每个连接可以处理多个客户端调用 (OSF_SCALL),但在每个给定时间,仅允许在连接上运行一个调用,而其他调用则排队。
因此,一个使用队列的有趣函数是 OSF_SCONNECTION::MaybeQueueThisCall。 它作为调度已到达连接的新调用的一部分进行调用。在这种情况下,队列用于在处理另一个调用时 “保持” 传入调用。
因此,我们有一种用户控制的方式来填充队列(通过一个接一个地发送客户端调用),但此函数提出了一个要求:连接当前正在处理一个调用。这意味着如果我们想要填充队列,我们需要有一个需要时间才能完成的调用。在处理调用时,我们将发送多个新调用,这些调用将填满调度队列。
什么样的函数调用需要最长的时间才能完成?
- 最佳候选者是可以在其中引起无限循环的函数。
- 第二个最佳选择是身份验证强制漏洞,因为服务器会连接到我们 - 因此,我们可以控制响应时间。
- 最后的手段是具有复杂逻辑的复杂函数或处理大量数据并因此需要大量时间才能完成的函数。
我们决定使用我们自己的身份验证强制漏洞。
触发所需的时间
到目前为止,我们了解了填充队列需要什么以及如何完成。 但一个重要的问题出现了 —— 它是否是实用的?
我们对发生整数溢出的变量的控制程度最低。一次只能递增一个,类似于 refcount(引用计数)溢出。这种整数溢出比整数溢出略差,整数溢出是我们完全控制的两个变量相加或相乘,或者当添加的大小可以在一定程度上控制时(例如,数据包大小)。
正如前面所描述的,我们必须分配 0x10000000 (~268M) 项。 这是非常庞大的数量。
尝试在我的计算机上触发漏洞的速度约为每秒 15 到 20 个排队调用。这意味着在普通机器上大约需要 155 天才能触发它!我们预计每秒会产生更多的排队调用。RPC 运行时间这么慢是有什么原因吗?它不是多线程的吗?
我们的假设是多个线程同时处理同一连接的不同调用并将其排队。 经过一番逆向工作,我们发现实际的流程有点不同。
MS-RPC 数据包处理
在调度调用之前,代码会旋转到一个新的线程(如果需要的话)并调用 OSF_SCONNECTION::TransAsyncReceive。 TransAsyncReceive 尝试在同一连接上接收请求。 然后它将请求提交给新线程(通过调用 CO_SubmitRead)。
另一个线程从 TppWorkerThread 中选取请求,最终导致 ProcessReceiveComplete,后者调用 MaybeQueueThisCall 将 SCALL 排队到调度队列中。然后,它向上传播并尝试接收对此连接的新请求。
因此,虽然我们可能有多个线程在运行,但实际上只有一个线程用于连接。 这意味着我们无法同时将多个线程的调用添加到队列中。
数据包 “剩余”
我们试图找到每秒进行更多调用的方法,以最大限度地减少触发漏洞所需的时间。在逆向接收代码时,我们注意到,如果数据包的长度大于数据包中的实际 RPC 请求,则 RPC 运行时会保存剩余部分。稍后,当它检查新请求时,它不会立即使用套接字。它会首先检查是否有数据包 “剩余”,如果有,它会根据剩余数据提供新的请求。
这让我们能够发送更少的数据包,每个数据包都包含最大数量的请求。当我们尝试这样做时,每秒排队的调用数量保持相对不变,因此这似乎是没有任何帮助的。
总结
尽管预计利用这些漏洞的可能性很低,但我们已将它们添加到我们去年对 MS-RPC 研究中发现的重要漏洞列表中。 重要的是要记住,即使是难以利用的漏洞对于有能力(且有耐心)的攻击者来说也是一个机会。
虽然 MS-RPC 已经存在了几十年,但它仍然存在有待发现的漏洞。我们希望这项研究能够鼓励其他研究人员研究 MS-RPC 及其所呈现的攻击面。 我们要感谢 Microsoft 的快速响应并解决问题。
欢迎关注 Akamai ,第一时间了解高可用的 MySQL/MariaDB 参考架构,以及丰富的应用程序示例。
相关文章:
远离远程代码执行 ,RPC 运行时中的三个漏洞是如何被发现的?
引言 MS-RPC 是 Windows 网络中广泛使用的协议,许多服务和应用程序都依赖它。 因此,MS-RPC 中的漏洞可能会导致严重后果。 Akamai 安全情报小组在过去一年中一直致力于 MS-RPC 研究。 我们发现并利用了漏洞,构建了研究工具,并编写…...
零基础学python之高级编程(4)---python异常类型及其类型处理
python异常类型及其类型处理 文章目录 python异常类型及其类型处理前言一、异常的概念二、异常类型1.捕获异常方法2.主动抛出异常 总结 前言 我们在日常学习中或者在开发一个项目时,一定会出现的问题就是报错,今天我们就学习错误类型的种类以及错误类型的处理方法 一、异常的概…...
如何实现三维模型在网页/手机端/APP上的展示与分享?
在四维轻云平台中,只需要简单几步,就能轻松实现三维模型在网页/手机端/APP上的交互展示,也可分享转发给他人进行在线查看。 1、注册登录 打开四维轻云官网,完成注册并登录。 2、创建项目 在【项目管理】中点击“新建项目”按钮…...
SpringBoot项目在进行部署打包的时候,打包成jar和war有何差异?
首先给大家来讲一个我们遇到的一个奇怪的问题: 我的一个springboot项目,用mvn install打包成jar,换一台有jdk的机器就直接可以用java -jar 项目名.jar的方式运行,没任何问题,为什么这里不需要tomcat也可以运行了? 然…...
ARM系列 -- 虚拟化(四)
今天来看看虚拟中断。 在一个非虚拟化的系统中,操作系统可以直接访问GIC的寄存器,并且处理GIC的物理中断接口(physical interrupt interface)。 但是在一个虚拟化的系统中,不是这样。Guest OS并不知道它运行在虚拟系…...
QT GUI编程常用控件学习
1 GUI编程应该学什么 2 QT常用模块结构 QtCore: 包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用 QtGui: 包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类 QtWidgets: 包含了一些列创建桌面应用的UI元素…...
【Python从入门到进阶】49、当当网Scrapy项目实战(二)
接上篇《48、当当网Scrapy项目实战(一)》 上一篇我们正式开启了一个Scrapy爬虫项目的实战,对当当网进行剖析和抓取。本篇我们继续编写该当当网的项目,讲解刚刚编写的Spider与item之间的关系,以及如何使用itemÿ…...
flutter build ipa 打包比 xcode archive 打出的ipa包大
为什么 flutter build ipa 打包比 xcode archive 打出的ipa包大? 如果你用Flutter构建的.ipa文件比通过Xcode Archive构建的.ipa文件要大,这可能是因为Flutter构建了一个包含了多平台的二进制文件的通用包。这意味着在Flutter构建的.ipa中包含了所有的C…...
B端系统:巧妙地容错和防错设置,减少用户操作错误
Hi,大家好,我是大美B端工场,从事8年前端开发的老司机。很多B端系统体验不好,让用户非常茫然或者容易出错,大大降低了操作体验,本文着重分析B端系统的容错机制该如何设计,欢迎老铁们关注、评论、…...
BIO实战、NIO编程与直接内存、零拷贝深入辨析
BIO实战、NIO编程与直接内存、零拷贝深入辨析 长连接、短连接 长连接 socket连接后不管是否使用都会保持连接状态多用于操作频繁,点对点的通讯,避免频繁socket创建造成资源浪费,比如TCP 短连接 socket连接后发送完数据后就断开早期的http服…...
PDF文件转换为图片
现在确实有很多线上的工具可以把pdf文件转为图片,比如smallpdf等等,都很好用。但我们有时会碰到一些敏感数据,或者要批量去转,那么需要自己写脚本来实现,以下脚本可以提供这个功能~ def pdf2img(pdf_dir, result_path…...
【Java程序设计】【C00317】基于Springboot的智慧社区居家养老健康管理系统(有论文)
基于Springboot的智慧社区居家养老健康管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的智慧社区居家养老健康管理系统设计与实现,本系统有管理员、社区工作人员、医生以及家属四种角色权限 管…...
Vue3前端实现一个本地消息队列(MQ), 让消息延迟消费或者做缓存
MQ功能实现的具体代码(TsMQ.ts): import { v4 as uuidx } from uuid;import emitter from /utils/mitt// 消息类 class Message {// 过期时间,0表示马上就消费exp: number;// 消费标识,避免重复消费tag : string;// 消息体body : any;constr…...
普中51单片机学习(8*8LED点阵)
8*8LED点阵 实验代码 #include "reg52.h" #include "intrins.h"typedef unsigned int u16; typedef unsigned char u8; u8 lednum0x80;sbit SHCPP3^6; sbit SERP3^4; sbit STCPP3^5;void HC595SENDBYTE(u8 dat) {u8 a;SHCP1;STCP1;for(a0;a<8;a){SERd…...
Python 实现Excel自动化办公(上)
在Python 中你要针对某个对象进行操作,是需要安装与其对应的第三方库的,这里对于Excel 也不例外,它也有对应的第三方库,即xlrd 库。 什么是xlrd库 Python 操作Excel 主要用到xlrd和xlwt这两个库,即xlrd是读Excel &am…...
DayDreamInGIS 之 ArcGIS Pro二次开发 图层属性中换行符等特殊字符替换
具体参考ArcMap中类似的问题,本帖开发一个ArcGISPro版的工具 1.基础库部分 插件开发,经常需要处理图层与界面的交互。基础库把常用的交互部分做了封装,方便之后的重复使用。 (1)下述类定义了数据存储结构࿰…...
RK3568平台 RTC时间框架
一.RTC时间框架概述 RTC(Real Time Clock)是一种用于计时的模块,可以是再soc内部,也可以是外部模块。对于soc内部的RTC,只需要读取寄存器即可,对于外部模块的RTC,一般需要使用到I2C接口进行读取…...
番外篇 | YOLOv5+DeepSort实现行人目标跟踪检测
前言:Hello大家好,我是小哥谈。DeepSort是一种用于目标跟踪的深度学习算法。它结合了目标检测和目标跟踪的技术,能够在视频中准确地跟踪多个目标,并为每个目标分配一个唯一的ID。DeepSort的核心思想是将目标检测和目标跟踪两个任务进行联合训练,以提高跟踪的准确性和稳定性…...
认识Sass
sass中文文档: Sass: Sass 文档 1. sass的安装步骤 1. 卸载冲突的Node.js (1) winR输入control,找到电脑上的卸载软件,找到Node.js,右键”卸载” (2) winR输入cmd,输入命令:node -v查看结果。 如果提示: node 不…...
YOLOv9-Openvino和ONNXRuntime推理【CPU】
1 环境: CPU:i5-12500 Python:3.8.18 2 安装Openvino和ONNXRuntime 2.1 Openvino简介 Openvino是由Intel开发的专门用于优化和部署人工智能推理的半开源的工具包,主要用于对深度推理做优化。 Openvino内部集成了Opencv、Tens…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
