CVE-2022-24125 和 CVE-2022-24126 的文档和概念验证代码。
黑暗之魂3 于 2022/08/25 发布了新游戏更新 1.15.1,同时恢复了在线服务。该更新修复了 CVE-2022-24125 和 CVE-2022-24126,以及游戏中 P2P 网络通信中存在的各种其他潜在安全漏洞(越界读/写)。此外,所有已知的能够损坏其他玩家存档的漏洞利用均已被修复。许多在在线多人游戏中经常遇到的常见低级作弊(例如“诅咒匕首”)也已被修补。
本仓库包含影响 FROM SOFTWARE 游戏的最新 RCE 漏洞利用概念验证代码和文档,即 CVE-2022-24126。虽然理论上其他游戏也存在此漏洞,但本研究的重点对象是黑暗之魂3。目前概念验证代码仅针对黑暗之魂3,但已确认该漏洞存在于以下游戏中:
易受攻击的代码同样存在于只狼中(致谢:LukeYui),尽管目前没有触发它的方法。恶魔之魂中是否存在该漏洞尚未确认,但可能性极大。虽然封闭网络测试受此影响,但艾尔登法环的正式版不受影响。 事实上,黑暗之魂3 中存在的大量网络崩溃、越界读/写以及允许玩家修改对等方游戏数据的漏洞利用,在艾尔登法环中均已被修补。感谢 LukeYui 汇编了这份清单,也感谢 FROM SOFTWARE 迅速采取行动!我很高兴地说,就黑客所能造成的破坏程度而言,艾尔登法环无疑是 FROM SOFTWARE 最安全的作品。
与普遍看法相反,这不是一个点对点网络漏洞利用。它与匹配服务器有关,因此严重得多,因为由于另一个匹配服务器漏洞(CVE-2022-24125),你无需参与任何多人游戏活动便会受到攻击。
鉴于在服务器关闭前的几个月里,该游戏平均同时在线玩家数约为 20,000 人,这显然是一个需要立即修复的问题,尤其是考虑到它有可能出现在艾尔登法环中。由于在我提交初始报告(附概念验证视频和详细的漏洞利用文档,本 README 的大部分内容即基于此)超过 40 天后,FROM SOFTWARE 仍未采取行动,我决定以无害的方式公开演示该漏洞存在的证据,希望通过引起关注促使开发人员解决它,而这一做法奏效了。
关于这 3 个 gadget 的更多细节,请参见此处。如果对于其他游戏,这种虚函数调用方法不可行,仍可利用任意代码重定向来搭建更传统的 ROP 漏洞利用。
要运行概念验证代码,你必须先有一个可供连接的服务器。虽然官方服务器因该漏洞已被关闭,但你可以使用 ds3os 搭建一个私有服务器。ds3os 旨在尽可能贴近正式服务器行为,但该项目已经部署了安全补丁以修复此漏洞。不过,你仍然可以通过自行构建该项目来搭建测试环境,只需在 BuildConfig.h 中将 SEND_MESSAGE_TO_PLAYERS_SANITY_CHECKS 和 NRSSR_SANITY_CHECKS 常量设置为 false。这将模拟不安全的正式服务器行为。请按照 ds3os 提供的说明启动游戏并连接到你的服务器。
完成上述步骤且游戏已连接至服务器后,构建 PoC 代码并启动 Injector.exe 可执行文件。它会在黑暗之魂3 进程中注入一个包含漏洞利用代码的 DLL。该 DLL 随后会使用向服务器发送 FRPG 消息的游戏函数,将漏洞利用投递到你自己的客户端。
函数 140ca5010 会检查条目大小,但 140ca4fa0 用于变长条目,不会对 size 字段执行健全性检查(Bug #1)。要实现上述任意代码重定向漏洞利用,我们需要将其设置为 14F3B0。这将导致约 1.3MiB 的越界读取,但内存页应该足够大,不会引发访问违规。
140ca56b0该函数由上一个函数以 nrssr_data 作为参数调用。它在栈上创建 DLMemoryInputStream 对象,然后将其作为参数传递给 NRSSR 解析器。
141955f50: ParseNRSessionSeachResultNRSessionSearchResult 解析器。验证 NRSSR 签名和版本号(14196a0f0),解析属性列表(14196a260)、主机名(14195603a)以及一些其他信息(参见 rce.h)
14195603a上述函数中不安全地复制主机名的循环(Bug #2)。以下是一些有助于跟踪缓冲区溢出期间发生情况的地址:
14F128DLMemoryInputStream 栈地址:14F3A0DLMemoryInputStream vtable 指针:1439e8b30DLInputStreamReader 使用的 DLMemoryInputStream 中虚函数的偏移量:0x181439e8b48MOV RCX,qword ptr [RCX + 0x8]
MOV RAX,qword ptr [RCX]
JMP qword ptr [RAX + 0x40]
这是由被覆盖的内存流 vftable 引起第一次代码重定向后我们到达的地方。虚函数调用重定向链自此开始。
针对黑暗之魂3 Ver. 1.15。理论上最大的 payload 大小取决于栈布局,因此会因游戏和版本而异。 ↩