Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Bad_Hoist-WriteUp — 关于Sleirsgoevy版本的CVE-2018-4386漏洞利用实现(由Fire30开发,名为Bad_Hoist)的分析报告 | Kitploit
工具/GitHubGitHub/a0zhar/bad_hoist-writeup
漏洞分析漏洞利用Web应用程序漏洞利用论文与研究学习与教育二进制利用
GitHuba0zhar/bad_hoist-writeup

Bad_Hoist-WriteUp

关于Sleirsgoevy版本的CVE-2018-4386漏洞利用实现(由Fire30开发,名为Bad_Hoist)的分析报告

查看仓库
11年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Sleirsgoevy 版本的 Bad_Hoist(技术分析)| CVE-2018-4386

[!Note] 关于 PS4 的背景信息:
PlayStation 4 主机采用定制的 AMD x86-64 CPU(8 核心),其 Orbis OS 基于 FreeBSD(v9.0),并包含部分 NetBSD 代码。 它还集成了大量开源软件,例如 Mono VM 和 WebKit。

PS4 互联网浏览器:

PS4 使用的互联网浏览器实际上基于开源 WebKit 项目构建。 WebKit 是一个开源布局引擎,为 iOS、Wii U、3DS、PS Vita 和 PS4 的浏览器渲染网页。

WebProcess:

PS4 的互联网浏览器实际上由两个独立的进程组成。 我们劫持以实现代码执行的是 WebKit 核心进程(负责处理 HTML 和 CSS 解析、图片解码、JavaScript 执行等)。 另一个进程负责其他所有事务:显示图形、接收手柄输入、管理历史和书签等。

堆分配器

PS4 WebKit 浏览器使用了多个堆分配器,分别服务于不同组件。具体如下:

  • FastMalloc 是标准分配器,被许多 WebKit 组件使用。
  • IsoHeap 供 DOM 引擎使用,其目的是按类型对每个分配进行分类,以缓解 UAF 漏洞。
  • 垃圾回收器 由 JavaScript 引擎用于分配 JavaScript 对象。
  • IsoSubspace 也由 JavaScript 引擎使用,其目的与 IsoHeap 相同,但仅用于少数对象。
  • Gigacage 实现了缓解措施,防止对特定对象的越界读/写。如前所述,该功能在 PS4 上已禁用。

Bad_Hoist

CVE-2018-4386 的核心是 WebKit(v605.1.15,即 PS4 固件 6.XX 使用的版本)中 JavaScriptCore (JSC) 引擎的一个逻辑缺陷。该缺陷位于 BytecodeGenerator::hoistSloppyModeFunctionIfNecessary 函数中,涉及对非严格模式 JavaScript 中变量提升的不正确处理,特别是在 for-in 循环内部。

易受攻击的组件(ForInContext): 我们主要针对的是 ForInContext。这是 JavaScriptCore 用于管理 for-in 循环状态的内部结构,跟踪当前迭代变量以及正在枚举的属性集合。

当函数声明在 for-in 循环内被提升时,如果迭代变量被覆盖,引擎应使相关的 ForInContext 对象 失效。然而,由于该漏洞,此失效不会发生。这使得迭代变量可以被 任意对象 替换。尽管如此,引擎仍将该变量当作字符串属性名处理。

当稍后调用 op_get_direct_pname 字节码处理器时,它直接使用迭代变量作为字符串对象,而不进行类型检查。

通过传递一个精心构造的对象而非字符串,导致类型混淆,我们能够以导致内存损坏的方式利用此漏洞,甚至获得有用的利用原语,例如 addrof、fakeobj 和 任意读/写。

WebKit 内部原理:结构 ID 与类型混淆

结构 ID: JavaScriptCore 中的每个对象,包括内部表示(如 WTF::StringImpl),都有一个 结构 ID(或类型标签),用于告知引擎该对象的类型以及如何解释其字段。

类型混淆: 我们的漏洞利用 CVE-2018-4386 漏洞,使一个 JavaScript 对象被解释为 StringImpl。这就是 create_impl() 函数的目的,它返回一个类型混淆的 WTF::StringImpl 对象,然后可以将该对象作为我们之前在 漏洞机制 部分提到的任意对象传递给 trigger() 函数。

然而,为了使其工作,内存布局和结构 ID 必须与引擎对真实字符串对象的期望“足够接近”。

JSString::toIdentifier() 内部做了什么?

PS4 互联网浏览器 WebKit JavaScriptCore 引擎中有一个名为 JSString::toIdentifier() 的方法。该方法 将 JavaScript 字符串对象 (JSString) 转换为内部 Identifier 表示。

该 Identifier 在整个引擎中使用,用于高效地比较、存储和查找属性名、变量名以及其他需要被 JavaScript 引擎快速且频繁引用的字符串。

它会检查对象是否是一个有效的字符串,并且其结构 ID 是否匹配引擎对字符串对象的期望。如果字符串是一个 rope(字符串拼接),它可能会先将其展平,然后再进行转换。然后,它会为字符串检索现有的 Identifier,或者如果不存在则创建一个新的 Identifier。

该 Identifier 随后被内部用于快速的属性和变量查找。

JSString::toIdentifier() 检查的绕过方法

当漏洞利用进入迭代 1024 次的 for 循环时,每次迭代都会创建一个新的类型混淆的 WTF::StringImpl 对象,该对象包含由 create_impl() 函数返回的 32 个新的 结构 ID。当这个类型混淆的对象被用作任意对象并传递给 trigger() 时,JSC 会对其调用 JSString::toIdentifier()。

JSString::toIdentifier() 会检查结构 ID 中的某些位,以确认该对象是一个有效的字符串或可以被视为字符串处理。通过生成许多具有不同布局和结构 ID 的对象,漏洞利用增加了至少有一个对象的结构 ID 能够通过 JSString::toIdentifier() 内部检查的机会。

参考

  • Project Zero: CVE-2018-4386
  • Synacktiv 的文章
  • CTurt 的《Hacking the PS4》(三部分系列)
  • Fire30 的原始 Bad_Hoist
  • Sleirsgoevy 的 Bad_Hoist 版本
下载工具