
यह CVE-2017-7047 के लिए एक एक्सप्लॉइट है, जो 10.3.2 और उससे नीचे पर काम करता है।
triple_fetch - ianbeer [https://bugs.chromium.org/p/project-zero/issues/detail?id=1247]
यह CVE-2017-7047 के लिए एक एक्सप्लॉइट है, जो libxpc में एक तर्क त्रुटि है जिसने दुर्भावनापूर्ण संदेश भेजने वालों को xpc_data ऑब्जेक्ट भेजने की अनुमति दी जो साझा मेमोरी द्वारा समर्थित थे। xpc संदेशों के उपभोक्ताओं को यह उम्मीद नहीं थी कि xpc_data ऑब्जेक्ट के बैकिंग बफ़र्स को प्रेषक द्वारा संशोधित किया जा सकता है जबकि उन्हें प्राप्तकर्ता द्वारा संसाधित किया जा रहा हो।
यह प्रोजेक्ट CVE-2017-7047 का उपयोग एक proof-of-concept रिमोट lldb debugserver स्टब बनाने के लिए करता है जो iOS पर सभी userspace प्रक्रियाओं से जुड़ने और उनके रिमोट डिबगिंग की अनुमति देने में सक्षम है।
यह एक्सप्लॉइट का उच्च-स्तरीय अवलोकन है, गहन विवरण बाद में प्रकाशित हो सकता है। अभी के लिए कृपया अधिक विवरण के लिए कोड देखें :)
भाग I
यह एक्सप्लॉइट NSXPC को लक्षित करता है, जो कई iOS सेवाओं द्वारा उपयोग किया जाने वाला एक Objective-C Remote Procedure Call (RPC) कार्यान्वयन है (1)। एक NSXPC संदेश में एक mach संदेश के अंदर xpc सीरियलाइज़्ड xpc_data ऑब्जेक्ट के अंदर एक bplist16 सीरियलाइज़्ड ऑब्जेक्ट होता है।
अन्य चीजों के अलावा, bplist16 ऑब्जेक्ट में एक Objective-C प्रकार एन्कोडिंग स्ट्रिंग (2) होती है, जिसे CoreFoundation में फ़ंक्शन ___NSMS1 द्वारा पार्स किया जाएगा। यह फ़ंक्शन यह उम्मीद नहीं करता है कि जिस स्ट्रिंग को वह पार्स कर रहा है उसकी सामग्री बदल जाएगी, और यह एक्सप्लॉइट इसका उपयोग एक हीप ओवरफ्लो प्रिमिटिव बनाने के लिए करता है, इस तथ्य का फायदा उठाते हुए कि स्ट्रिंग का एक निश्चित भाग मेमोरी से तीन बार लाया जाएगा। तीन अलग-अलग, सावधानी से चुने गए मानों के बीच स्विच करके हम चुने हुए हीप आवंटन आकार से मनमाने बाइट्स के साथ बाहर ओवरफ्लो करने में सक्षम होते हैं।
minibplist16.c में bplist सीरियलाइज़ेशन का एक न्यूनतम कार्यान्वयन और यह कैसे काम करता है इसकी चर्चा शामिल है।
बाहरी xpc संदेश में heap groom होता है। यह XPC सीरियलाइज़ेशन प्रोटोकॉल के एक कस्टम कार्यान्वयन का उपयोग करके हीप को groom करता है, जिसमें टकराने वाली कुंजियों के साथ xpc डिक्शनरी बनाकर आवंटन और मुक्त प्रिमिटिव बनाए जाते हैं। बाहरी xpc संदेश में एक heap spray (मेमोरी उपयोग को कम रखने के लिए एक साझा मेमोरी ऑब्जेक्ट की कई प्रतियों का उपयोग करके) और एक mach port send right name spray भी होता है।
ओवरफ्लो एक Objective-C ऑब्जेक्ट के isa Class पॉइंटर को हीप-स्प्रे किए गए नकली ऑब्जेक्ट की ओर इंगित करता है, ताकि जब उस नकली ऑब्जेक्ट पर कोई मेथड कॉल किया जाए, तो स्टैक एक छोटे ROP स्टैक पर स्थानांतरित हो जाए। ROP स्प्रे किए गए mach port send right नामों के माध्यम से brute-force करता है, जिसमें लक्ष्य के send right को उसके स्वयं के task port पर प्रत्येक उम्मीदवार स्प्रे किए गए send right नाम को भेजने का प्रयास किया जाता है। एक्सप्लॉइट सभी स्प्रे किए गए पोर्ट्स पर सुनता है और यदि एक्सप्लॉइट सफल होता है, तो उसे लक्ष्य के task port के लिए एक send right प्राप्त होता है, जिस बिंदु पर उसका लक्ष्य कार्य पर पूर्ण नियंत्रण होता है।
मध्यांतर
यह एक्सप्लॉइट coreauthd डेमॉन द्वारा होस्ट की जाने वाली com.apple.CoreAuthentication.daemon सेवा को लक्षित करता है, जो root के रूप में चलता है। इस सेवा तक ऐप सैंडबॉक्स से पहुँचा जा सकता है। एक्सप्लॉइट को शुरू में काम करने के बाद मेरे द्वारा किए गए थोड़े प्रयोग से पता चला कि coreauthd के संदर्भ में processor_set_tasks API डिवाइस पर चल रही सभी userspace प्रक्रियाओं के task ports के लिए send rights प्राप्त करने में सक्षम है। यह कम से कम 2012 से सार्वजनिक ज्ञान है और इस इतिहास को प्रमुख iOS इंटरनल्स शोधकर्ता जोनाथन लेविन ने अपनी साइट (3) पर गहराई से कवर किया है। लेविन ने 2015 में जो कोड अपलोड किया था वह आज भी काम करता है - इसके लिए जेलब्रेक डिवाइस की आवश्यकता नहीं है, केवल एक स्टॉक डिवाइस पर root की आवश्यकता है।
भाग II
इस एक्सप्लॉइट के साथ मैं जो डिबगर बनाना चाहता था उसका मुख्य लक्ष्य एक मनमानी प्रक्रिया से जुड़ने, ब्रेकपॉइंट सेट करने और उनके हिट होने पर रजिस्टर और मेमोरी स्थिति का निरीक्षण और परिवर्तन करने में सक्षम होना था। gdb या lldb रिमोट प्रोटोकॉल को शुरू से लागू करने के बजाय, मैंने lldb debugserver प्रोजेक्ट में आवश्यक परिवर्तन करने का फैसला किया और फिर एक्सप्लॉइट का उपयोग इसे चलाने के लिए किया।
सॉफ़्टवेयर ब्रेकपॉइंट्स का उपयोग करने के बजाय, जिनके लिए कोड साइनिंग को अक्षम या बायपास करने की आवश्यकता होती है, debugserver को विशेष रूप से हार्डवेयर ब्रेकपॉइंट्स का उपयोग करने के लिए पैच किया गया है। ARM64 में 16 हार्डवेयर ब्रेकपॉइंट रजिस्टर होते हैं, जिसका अर्थ है कि आपके पास अधिकतम 16 सक्रिय ब्रेकपॉइंट्स हो सकते हैं।
lldb debugserver कोड में ARM हार्डवेयर ब्रेकपॉइंट्स के लिए प्रोटोटाइप समर्थन मौजूद था, लेकिन इसे काम करने के लिए कुछ हैकिंग की आवश्यकता थी। उदाहरण के लिए, मुझे ऐसा कोड जोड़ना पड़ा जो debugee में pthread_introspection_hook फ़ंक्शन पॉइंटर को हमेशा क्रैश करने के लिए पैच करता है, ताकि मैं नए थ्रेड्स के निर्माण का पता लगा सकूं और हार्डवेयर ब्रेकपॉइंट स्थिति को नए बनाए गए थ्रेड्स में प्रचारित कर सकूं और आगे बढ़ सकूं जैसे कि यह कभी क्रैश नहीं हुआ था।
मैंने attach और continue कोड को भी पैच किया है ताकि ptrace और सिग्नल का उपयोग करने के बजाय task port के माध्यम से सीधे कार्य को सस्पेंड और रिज़्यूम किया जा सके।
बिल्ड टिप्स
सब कुछ चाहिए 10.0 से 10.3.2 तक (समावेशी) चलने वाले सभी iOS डिवाइसों पर काम करना चाहिए। मैंने इस पर परीक्षण किया है:
मैंने एक पहले से निर्मित debugserver बाइनरी शामिल की है जिसका उपयोग करने का मैं सुझाव देता हूं, लेकिन lldb के debugserver के लिए पैच भी debugserver.diff में शामिल है।
debugserver बनाना बहुत कठिन नहीं है। मैं निम्नलिखित git रिविज़न पर काम कर रहा था:
lldb: 0db640c4cd1ec4e4c2580336fa5f53be029c5bc7 llvm: ec48fd127774a4b67c72ea7c3057b5c964375e77 clang: b6e778e0bfa2fc32f8821c6b33762f5cb6724659
आपूर्ति किए गए debugserver.diff को लागू करें।
बिल्ड के लिए आपको (हालिया) cmake और ninja चाहिए, आप इन्हें स्रोत या अपने पसंदीदा mac पैकेज मैनेजर से बाइनरी के रूप में प्राप्त कर सकते हैं।
(4) में MacOS पर एक सामान्य llvm बिल्ड सेट करने के तरीके के लिए एक गाइड है जो सहायक हो सकती है।
आपको अपने iOS SDK में कई हेडर फ़ाइलों को सिमलिंक करने की आवश्यकता होगी, कम से कम:
xpc/ launchd.h libproc.h sys/proc_info.h sys/kern_control.h net/route.h mach/mach_vm.h mach/shared_region.h sys/ptrace.h crt_externs.h
निम्नलिखित cmake इनकैंटेशन आपको आवश्यक सभी संकेत दे देगा:
cmake -G "Ninja" -DCMAKE_OSX_ARCHITECTURES="armv7;armv7s;arm64" -DCMAKE_TOOLCHAIN_FILE=../cmake/platforms/iOS.cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_RUNTIME=Off -DLLVM_INCLUDE_TESTS=Off -DLLVM_INCLUDE_EXAMPLES=Off -DLLVM_ENABLE_BACKTRACES=Off ../
ninja debugserver
फिर आपको debugserver बाइनरी को साइन या फेकसाइन करना होगा और आपूर्ति किए गए xcode प्रोजेक्ट में मौजूद बाइनरी को बदलना होगा।
कोडसाइनिंग
एक्सप्लॉइट प्रोजेक्ट डिफ़ॉल्ट रूप से mach_portal amfid हुक का एक बेहतर संस्करण स्थापित करेगा (इस बार फैट फाइलों के लिए काम करने वाले समर्थन और कोई हार्डकोडेड ऑफसेट नहीं :) )
यदि आप केवल चीजों को डिबग करना चाहते हैं, तो आपको अपने स्वयं के प्रमाणपत्र के साथ debugserver बाइनरी को साइन करने और amfid हुक को अक्षम करने में सक्षम होना चाहिए।
यदि आप amfid हुक का उपयोग करते हैं, तो ध्यान रखें कि जिस ऐप में यह चल रहा है वह अभी भी बैकग्राउंड कोड निष्पादन सीमाओं के अधीन है। ऐप beginBackgroundTaskWithName के माध्यम से अधिक समय का अनुरोध करता है।
उपयोग:
अपने होस्ट और लक्ष्य iDevice को एक ही वायरलेस नेटवर्क से कनेक्ट करें और iDevice का IP पता नोट करें।
एक्सप्लॉइट ऐप बनाएं और चलाएं। मैं इसे xcode के अंदर करने की सलाह देता हूं, लेकिन यह स्टैंडअलोन भी काम करेगा।
थोड़ा इंतज़ार करें। यदि यह कुछ मिनटों के बाद काम नहीं करता है, तो डिवाइस को हार्ड-रीबूट करें, थोड़ा इंतज़ार करें और फिर से प्रयास करें।
यदि यह काम करता है, तो इसे “patched debugserver listening on port 1234” प्रिंट करना चाहिए।
यदि आप “get process listing” बटन पर क्लिक करते हैं, तो आपको ps का आउटपुट देखना चाहिए।
(आउटपुट देखना आसान है यदि आप xcode का उपयोग करते हैं, लेकिन एक्सप्लॉइट आउटपुट भी दिखाएगा)
आप जिस लक्ष्य प्रक्रिया को डिबग करने में रुचि रखते हैं, उसे देखें और उसका pid नोट करें।
होस्ट पर कमांड लाइन से lldb लॉन्च करें:
$ lldb (lldb)
set the platform to ios remote: (lldb) platform select remote-ios
connect to the debugserver stub: (lldb) process connect connect://192.168.0.172:1234
(where 192.168.0.172 is the IP address of the iDevice)
attach to the process you’re interested in: (lldb) attach 55
...wait a bit, debugserver is running in verbose mode...
Process 55 stopped
Executable module set to "/usr/libexec/backboardd".
you’re attached :)
set a breakpoint: (lldb) break set --name malloc Breakpoint 1: 4 locations.
continue:
(lldb) c Process 55 resuming Process 55 stopped
malloc libsystem_malloc.dylibmalloc:
-> 0x1936161e0 <+0>: stp x20, x19, [sp, #-0x20]!
0x1936161e4 <+4>: stp x29, x30, [sp, #0x10]
0x1936161e8 <+8>: add x29, sp, #0x10 ; =0x10get a backtrace:
(lldb) bt
malloc frame #1: 0x0000000100099648 backboardd_mh_execute_header + 71240
frame #2: 0x00000001945bf218 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 frame #3: 0x00000001945be9cc CoreFoundation__CFRunLoopDoSource1 + 436
frame #4: 0x00000001945bc4b0 CoreFoundation__CFRunLoopRun + 1840 frame #5: 0x00000001944ea2b8 CoreFoundationCFRunLoopRunSpecific + 444
frame #6: 0x0000000194537b44 CoreFoundationCFRunLoopRun + 112 frame #7: 0x00000001000a5ba8 backboardd_mh_execute_header + 121768
frame #8: 0x00000001000a5bec backboardd_mh_execute_header + 121836 frame #9: 0x00000001936a5850 libsystem_pthread.dylib_pthread_body + 240
frame #10: 0x00000001936a5760 libsystem_pthread.dylib_pthread_start + 284 frame #11: 0x00000001936a2d94 libsystem_pthread.dylibthread_start + 4समस्या निवारण:
XCode का नवीनतम संस्करण स्थापित करें (8.3.3 के साथ विकसित और परीक्षण किया गया)
यदि lldb कनेक्ट विफल हो जाता है, तो सुनिश्चित करें कि आपके पास लक्ष्य iOS संस्करण के लिए SDK स्थापित है
चेतावनियाँ:
मुझे उम्मीद है कि मैं इन्हें ठीक कर दूंगा, लेकिन इस समय बहुत व्यस्त हूं, क्षमा करें!
अन्य PoCs चलाना:
यदि आप इस प्रोजेक्ट के pocs फ़ोल्डर में एक बाइनरी डालते हैं, तो आप डिवाइस पर UI में उसे चुनकर और "exec bundle binary" पर क्लिक करके एक्सप्लॉइट से उसे exec करा सकते हैं।
यह अभी भी ऐप सैंडबॉक्स के अंदर चलेगा, लेकिन यदि ऐप में privileged_task_port नामक एक सिंबल है, तो उसे launchd के task port के लिए एक send right दिया जाएगा। triple_fetch_sdk फ़ोल्डर में एक नमूना प्रोजेक्ट है जो दिखाता है कि आप इसका उपयोग PoCs बनाने के लिए कैसे कर सकते हैं, उदाहरण के लिए दिलचस्प प्रक्रियाओं में व्यवहार ट्रिगर करने के लिए, जिन्हें आप बाद में debugserver का उपयोग करके डिबग कर सकते हैं।
इसमें remote call/ports/files/memory APIs भी शामिल हैं, जो आपको अन्य प्रक्रियाओं में फ़ंक्शन कॉल करने और file descriptors, mach ports तथा मेमोरी को इधर-उधर स्थानांतरित करने की सुविधा देते हैं।
(1) [https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html] (2) [https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html] (3) [http://newosxbook.com/articles/PST2.html] (4) [https://gist.github.com/thlorenz/a068c202f2487ec13809]
इस प्रोजेक्ट में lldb पर आधारित कोड (debugserver.diff) और एक बाइनरी (debugserver) शामिल है, जो निम्नलिखित लाइसेंस के अधीन है:
University of Illinois/NCSA Open Source License
Copyright (c) 2010 Apple Inc. All rights reserved.
द्वारा विकसित:
LLDB Team
इसके द्वारा, इस सॉफ्टवेयर और संबंधित दस्तावेज़ीकरण फ़ाइलों ("सॉफ्टवेयर") की एक प्रति प्राप्त करने वाले किसी भी व्यक्ति को, बिना किसी शुल्क के, सॉफ्टवेयर के साथ व्यवहार करने की अनुमति प्रदान की जाती है, जिसमें बिना किसी प्रतिबंध के सॉफ्टवेयर की प्रतियों का उपयोग, प्रतिलिपि, संशोधन, विलय, प्रकाशन, वितरण, उपलाइसेंस, और/या बेचने के अधिकार शामिल हैं, और जिन व्यक्तियों को सॉफ्टवेयर प्रदान किया जाता है उन्हें ऐसा करने की अनुमति देने के लिए, निम्नलिखित शर्तों के अधीन:
स्रोत कोड के पुनर्वितरण में उपरोक्त कॉपीराइट सूचना, शर्तों की यह सूची और निम्नलिखित अस्वीकरण बनाए रखने चाहिए।
बाइनरी रूप में पुनर्वितरण को उपरोक्त कॉपीराइट सूचना, शर्तों की यह सूची और निम्नलिखित अस्वीकरण को वितरण के साथ प्रदान किए गए दस्तावेज़ीकरण और/या अन्य सामग्रियों में पुन: प्रस्तुत करना होगा।
LLDB Team, कॉपीराइट धारकों, या इसके योगदानकर्ताओं के नामों का उपयोग इस सॉफ्टवेयर से व्युत्पन्न उत्पादों के समर्थन या प्रचार के लिए विशेष पूर्व लिखित अनुमति के बिना नहीं किया जा सकता है।
सॉफ्टवेयर "जैसा है" (AS IS) प्रदान किया जाता है, बिना किसी प्रकार की वारंटी के, व्यक्त या निहित, जिसमें व्यापारिकता (merchantability), किसी विशेष उद्देश्य के लिए उपयुक्तता और अनुल्लंघनीयता (noninfringement) की वारंटी शामिल है, लेकिन इन्हीं तक सीमित नहीं है। किसी भी स्थिति में योगदानकर्ता या कॉपीराइट धारक किसी भी दावे, क्षति या अन्य दायित्व के लिए उत्तरदायी नहीं होंगे, चाहे वह अनुबंध, अपकृत्य (tort) या अन्यथा के कार्य में हो, जो सॉफ्टवेयर या सॉफ्टवेयर के उपयोग या अन्य लेन-देन के संबंध में, या उससे उत्पन्न हो।