- Texts.com टीम ने अपने जैसा ही एक standalone desktop app, macOS के लिए Meta Messenger, analyse करने की कोशिश की, लेकिन certificate pinning की वजह से proxy-based MITM analysis रुक गया
- Meta की certificate pinning app को सिर्फ उन्हीं certificates पर भरोसा करने देती है जिन्हें app ने allow किया है, जिससे user द्वारा बनाए गए certificate authority के जरिए requests intercept और decrypt करने का तरीका block हो जाता है
- Frida-based dynamic instrumentation में Messenger पर crashes और deployment complexity ज्यादा थी, इसलिए टीम ने छोटा और reproducible binary patch चुना
- Hopper analysis से पता चला कि अगर
IsUsingSandbox() को true return कराने के लिए 4 bytes बदले जाएं, तो custom sandbox इस्तेमाल होने पर SSL verification बंद करने वाला code path लिया जा सकता था
- Patched executable से original binary को replace करके signing संभालने के बाद proxy tool में headers, response body, request information देखी जा सकी
Texts.com ने Messenger का analysis क्यों किया
- Texts.com में Meta platform project संभाल रहे Batuhan İçöz ने माना कि macOS के लिए Messenger app उनकी कंपनी के model के करीब एक standalone desktop app है, इसलिए उसका analysis valuable होगा
- Network requests intercept करना entry barrier कम होने के कारण app behavior समझने का अच्छा पहला कदम है
- लेकिन Meta ने app में certificate pinning लागू करके security model मजबूत किया और user द्वारा खुद अपने against किए जाने वाले MITM analysis को भी रोक दिया
Certificate pinning क्या रोकती है
- Proxy client से requests intercept करने के लिए user को अपनी बनाई हुई certificate authority set up और trust करनी होती है
- उस certificate authority द्वारा जारी certificates के जरिए request information intercept और decrypt की जा सकती है
- अगर कोई service certificate pinning implement करती है, तो app सिर्फ किसी खास certificate authority द्वारा जारी certificates ही accept करता है
- ऐसे में user द्वारा बनाया गया certificate valid नहीं होता, इसलिए requests intercept नहीं की जा सकतीं
Patch से पहले की स्थिति और लक्ष्य
- Certificate pinning बंद न करने पर सभी requests “Internal Error” return करती हैं
- Proxy software में “SSL Handshake Failed” दिखता है और request lifecycle अंत तक proceed नहीं करता
- इस स्थिति में request contents infer करना मुश्किल है
- लक्ष्य था कि network debugging tools में requests, responses, headers सीधे पढ़े जा सकें
असफल bypass विकल्प और अंतिम चुनाव
- पहले काम कर चुका एक तरीका binary के अंदर URL string को ऐसे self-hosted endpoint से बदलना था जो TLS implement नहीं करता
- यह endpoint client और server के बीच requests और responses pass करता है
- Messenger जैसे बड़े app की तुलना में यह छोटे apps के लिए ज्यादा suitable है
- Frida जैसी dynamic instrumentation library भी candidate थी, लेकिन Messenger पर stability कम थी
- Hook लगाते समय crashes अक्सर होते थे
- Overhead की वजह से problematic point ढूंढना मुश्किल था
- चलाने के लिए environment और tool configuration चाहिए था, इसलिए teammates को deploy करना complex था
- कई वर्षों से maintain किया गया Frida script भी try किया गया
- यह script आम certificate pinning libraries और bypass methods के लिए इस्तेमाल होता था और ज्यादातर apps में काम करता था
- Meta apps इस “ज्यादातर” में शामिल नहीं थे
- आखिर में टीम ने ऐसा binary patch चुना जिससे certificate pinning पूरी तरह बंद हो सके और जिसे teammates को आसानी से दिया जा सके
Hopper से मिला patch point
- Messenger download करके Applications folder में ले जाने के बाद
/Applications/Messenger.app/Content/MacOS/Messenger के compiled ARM binary को Hopper में import किया गया
- Hopper compiled binaries को disassemble, decompile, recompile, debug और visualize कर सकता है
- Binary और references load होने के बाद
certificate, ssl, pinning जैसे terms search किए गए
"SSL pinning verification failed for host:" string analysis का starting point बनी
- Compiled binary को ज्यादा modify करने पर crash हो सकता है, इसलिए strategy थी कि जितना हो सके उतना छोटा change किया जाए
- Ideal change boolean value flip करना, condition reverse करना, या कुछ instructions modify करने जैसा narrow-impact patch होता है
IsUsingSandbox() को हमेशा true बनाना
- Control flow graph से execution flow visualize किया गया और connected references follow करके ऊपर की ओर trace किया गया
"Using custom sandbox -> turn off SSL verification" string मिली
- इस flag को तय करने वाले function के references file में search किए गए, और procedure के top पर वह reference दिखा
IsUsingSandbox() function में return value assign होने वाली जगह trace की गई
w0 register w19 से move होने के बाद return होता है
w19 मूल रूप से load byte instruction से assign होता है
- अगर
w19 को load करने के बजाय हमेशा true पर set किया जाए, तो IsUsingSandbox() true return करता है
- पहले मिली string के अनुसार custom sandbox use होने पर SSL verification बंद हो जाता है, इसलिए इस change से certificate pinning disable हो जाती है
Original
ARM: ldrb w19, [sp, #0x40 + var_20]
HEX: F3 83 40 39
Rewritten
ARM: mov w19, #1
HEX: 33 00 80 52
- यह replacement hexadecimal mode में application के byte code को सीधे modify करके किया गया
Execution result और re-signing
- Hopper के “Produce New Executable” option से नया executable export किया गया
- Executable की signature हटाने के बाद original Messenger binary को नए binary से replace किया गया
- Messenger दोबारा run करने पर proxy tool में headers, response body, और अन्य request information दिखने लगी
- कुल binary size 97,477,728 bytes में से सिर्फ 4 bytes modify करके request interception possible हो गया
- अगर iOS पर similar approach देखनी हो, तो Hassan Mostafa का 2020 का Instagram certificate pinning bypass post देखा जा सकता है
- उस post में jailbroken iPhone पर conditional branch instruction flip करके Instagram certificate pinning हटाने का case है
- Compiled binary Batuhan को दी गई
- Batuhan ने signing certificate हासिल और install करने के बाद application को sign किया
- इसके बाद वह अपने system पर उस binary का इस्तेमाल करके अपनी requests देख सके
codesign --force --deep -s CERTNAME_OR_ID /Applications/Messenger.app
1 टिप्पणियां
Hacker News टिप्पणियाँ
मैं भी लगभग इसी रास्ते पर गया था, लेकिन डिकंपाइल/मॉडिफाई/रीकंपाइल तक जाने की नौबत आते ही छोड़ दिया।
इस स्तर तक पहुँचना सच में ज़बरदस्त दृढ़ता है, और जानना दिलचस्प होगा कि इसमें वास्तव में कितने घंटे लगे। मैंने अपने लिए एक stop condition तय कर रखी थी और उसी का पालन किया।
शुरुआत में मैंने 2 घंटे तक अलग-अलग commands बदलकर देखीं और फिर छोड़ दिया। बाद में reverse engineer “Hassan Mostafa” (cyclon3) का पुराना लेख देखा, जिसमें उसने इसी तरीके से सफलता पाई थी—यानी iOS के Instagram पर Hopper Disassembler लागू किया था—तो उसी रात फिर कोशिश की, लेकिन फिर भी असफल रहा। वही commands ढूँढकर बदलकर भी देखा।
फिर मैंने इसे छोड़ने का फैसला किया, और कुछ हफ़्तों बाद, थोड़ा-सा खटकने के साथ अचानक दोबारा कोशिश की, तो sandbox function मिल जाने के बाद करीब 30 मिनट में काम हो गया।
ऐसा लगता है कि eBPF का इस्तेमाल करके TLS encryption से पहले data पढ़ा जा सकता है: Debugging with eBPF Part 3: Tracing SSL/TLS connections https://blog.px.dev/ebpf-openssl-tracing/
असली app traffic को intercepting proxy के ज़रिए route करने से, मक़सद के हिसाब से काफ़ी समय बच सकता है। उदाहरण के लिए, अगर आप authentication/session setup के बाद ही होने वाली requests में किसी एक parameter को अपने-आप बदलना चाहते हैं, तो पूरा शुरुआती flow करने वाला नया client लिखने या eBPF filter में modification logic डालने की बजाय app को अपना काम करने देना और proxy में सिर्फ़ एक जगह बदलाव करना कहीं ज़्यादा तेज़ है।
rustlsको statically link करता है।यह बहुत चतुर तरीका है। हालांकि, ऐसा लगता है कि sandbox mode में भी certificate pinning लागू कराना संभव रहा होगा।
कॉलेज के दिनों में मैंने Snapchat को man-in-the-middle attack से देखने की कोशिश की थी, लेकिन वहाँ भी certificate pinning थी, इसलिए आख़िरकार उसे तोड़ नहीं पाया।
entry point तक नहीं मिल पाया। अपेक्षाकृत छोटे social media app के लिए भी 2015 में उसकी security बेहिसाब मज़बूत थी।
sandbox mode में certificate pinning इस्तेमाल की गई होती, तब भी pin किए गए certificate check को हटाने का कोई दूसरा तरीका होने की पूरी संभावना थी।
अब नहीं, लेकिन पहले ज़रूर।
यह पोस्ट देखकर +Orc का ज़माना याद आ गया। अनचाही branch ढूँढकर उसे NOP करना जैसी चीज़ें तब आम जानकारी थीं, और लगता है कि उस दौर का बहुत-सा ज्ञान अब खो गया है।
आजकल सीखने के लिए तकनीकें कहीं ज़्यादा हैं, तो यह स्वाभाविक भी है।
[1]: https://en.m.wikipedia.org/wiki/Old_Red_Cracker
फिर भी मुझे लगता है कि NOP patching आज भी बहुत लोग करते हैं। बस complexity बढ़ गई है। DRM तोड़ने या किसी भी random mobile app को hex editor वगैरह से देखने वाले लोग अब भी हैं।
आज के programs ज़्यादा complex हैं, इसलिए शुरुआत करना कठिन हो गया है, लेकिन साथ ही ज़रूरी knowledge पहले से ज़्यादा accessible भी हो गई है।
अगर आप Meta app traffic intercept करना चाहते हैं, तो ज़रूरी नहीं कि ऐसा ही करें।
https://www.facebook.com/whitehat/bugbounty-education/261571...
सोच रहा हूँ कि इस तरह के modification को मुश्किल बनाने में runtime binary checksum मददगार होता या नहीं।
क्या mobile apps में यह standard practice नहीं है? क्या iOS या Android SDK ऐसी सुविधा देते हैं? लगता है कि इसे official release process से जोड़ा जा सकता है, और अपने-अपने non-jailbroken platforms पर enforce भी किया जा सकता है।
यह बुनियादी सवाल है, लेकिन चूँकि अंतिम समाधान binary के कुछ bytes बदलने का था, इसलिए लगा कि इसे रोका जा सकता था।
non-jailbroken platforms पर आम तौर पर यह developer certificate से किया जाता है।
Meta की, कम-से-कम Messenger की, reverse engineering defense काफ़ी ढीली लगती है।
advanced obfuscation तक जाए बिना भी, production build में
IsUsingSandbox()को पूरी तरह हटाना आसान होना चाहिए था।certificate pinning का मक़सद attacker के लिए tampering मुश्किल बनाना था, user के लिए नहीं।
जब मैंने पहली बार app crack किया, तो मुझे लगा था कि यह निश्चित रूप से fail होगा, लेकिन पता चला कि इस तरह modify करने में आसान JNE/JEZ points ढूँढना उम्मीद से आसान था।
अगर ग़लत चुन लें, तो बस original file पर वापस जाएँ और कोई दूसरा point आज़मा लें।
लगता है कि AI इस तरह का काम आसानी से automate कर सकता है। कई candidate points पर JEZ/JNZ उलटकर app चलाइए, फिर बस यह देखिए कि nag screen आती है या नहीं।
अगर failure condition अच्छी तरह define हो, तो बात आख़िरकार candidates कम करने की ही है।
हाँ, अगर AI Denuvo जैसी चीज़ को 0-shot में तोड़ दे, तो वह अलग बात होगी।
यह सोचने वाली बात है कि इतनी बड़ी कंपनी का application पूरी तरह obfuscate क्यों नहीं किया गया, और modified binary चलने से रोकने के लिए पर्याप्त safeguards भी क्यों नहीं लगाए गए
अगर कोई व्यक्ति/समूह/सरकार काफ़ी skilled हो या उसके पास मज़बूत motivation हो, तो वह आखिरकार इसे bypass कर ही लेगा। Client binary distribute करने की प्रकृति ही ऐसी होती है
इसे रोकने में बहुत समय और पैसा लगाया जा सकता है। पहले Pinterest अपना खुद का language और virtual machine distribute करना चाहता था, लेकिन मैं उसके खिलाफ था। या फिर आप यह मानकर चल सकते हैं कि client code मूलतः पहले से compromised है, और logic को server पर रखकर आगे बढ़ सकते हैं
Certificate pinning लगभग मुफ़्त जैसा है, और यह “इस key से बेहतर कुछ होना चाहिए तभी entry मिले” जैसी व्यवस्था है। यह पूरी तरह secure नहीं है, लेकिन इधर-उधर की कोशिशों को छाँट देता है
हाँ, इसका reverse engineering पर भी असर पड़ता है, लेकिन वह ज़्यादातर एक अतिरिक्त लाभ जैसा है
आखिरकार code user के device पर चलता है, और user यह देख सकता है कि code क्या कर रहा है, इसलिए deobfuscation हमेशा संभव है। अगर एक व्यक्ति इसे खोलकर नतीजा साझा कर दे, तो उसकी नकल करना भी बहुत आसान हो जाता है। इसका मतलब यह नहीं कि obfuscation बेकार है, लेकिन यह ऐसी चीज़ भी नहीं जिस पर बहुत ज़्यादा समय लगाया जाए
अगर attacker को device तक physical access मिल गया, तो उस बिंदु के बाद उसे रोकने का कोई तरीका नहीं रहता। आप बस इतना कर सकते हैं कि प्रक्रिया को इतना झंझटभरा बना दें कि वह चिढ़कर छोड़ दे
Obfuscation का इस experiment के नतीजों पर शायद लगभग कोई असर नहीं पड़ता, हाँ इतना हो सकता था कि approach थोड़ा और dynamic instrumentation की तरफ़ शिफ्ट हो जाती। मैंने जो सबसे प्रभावी obfuscation देखी है, वह VM obfuscation थी, लेकिन उसका performance impact काफ़ी बड़ा होता है। Obfuscation सामान्य debugging को भी और मुश्किल बना देती है
Modified binary रोकना system level पर किया जाता है, और application level पर भी implement किया जा सकता है, साथ ही यह काफ़ी आम भी है। लेकिन उस feature को भी bypass किया जा सकता है, और security checks पूरे होने के बाद Frida जैसी dynamic instrumentation library से modification भी किया जा सकता है
Meta के नज़रिए से reverse engineers के साथ cat-and-mouse game खेलना शायद सबसे अच्छा विकल्प नहीं होगा
यह जानने की जिज्ञासा है कि लेख में कौन-सा proxy tool इस्तेमाल किया गया था। क्या उसे चलने के दौरान सभी application traffic उसी के ज़रिए route किया जाता है?
अगर यह बेवकूफ़ी भरा सवाल हो तो माफ़ कीजिए
macOS पर सभी application traffic को उसके ज़रिए route किया जा सकता है, और device पर self-signed certificate install करने के बाद proxy से connect करके iOS device को भी proxy किया जा सकता है