
यह 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