1 पॉइंट द्वारा GN⁺ 2024-10-18 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Chromium की WebUI privilege boundary, enterprise policy testing feature, और DevTools extension API की खामियां आपस में जुड़ गईं, जिससे एक malicious Chrome extension बहुत कम user interaction के साथ shell command execution तक पहुंच सकती थी
  • attack path में chrome://policy पर undocumented policy testing API को कॉल करके user policy बदली जाती थी, और Browser Switcher के alternative browser path व arguments को shell command के रूप में abuse किया जाता था
  • chrome.devtools.inspectedWindow.reload() injectedScript execution की अनुमति देता था, और WebUI navigation के समय access blocking में देरी या crash के बाद बचे Page.reload request की वजह से privileged WebUI में code चलाया जा सकता था
  • Google ने इस vulnerability को P1/S1 के रूप में classify किया और Page.reload के loaderId validation, inspectedWindow.reload() URL check, और WebUI handler में policy testing enablement check जोड़ा
  • संबंधित vulnerabilities को CVE-2024-5836 और CVE-2024-6778 सौंपे गए, दोनों को CVSS 8.8 High मिला, और अंतिम bounty $20,000 थी

Chromium WebUI और sandbox boundary

  • Chromium untrusted code को sandbox के अंदर चलाता है, और Chrome extension का JavaScript भी केवल दिए गए permissions और accessible APIs के भीतर ही काम करना चाहिए
  • extension permissions के दम पर login info या browser history चुराई जा सकती है, लेकिन सिद्धांततः उसका असर browser के अंदर ही सीमित रहना चाहिए
  • Chromium के GUI का कुछ हिस्सा chrome://settings, chrome://history जैसे WebUI के रूप में implement किया गया है
    • WebUI HTML, CSS, JavaScript में लिखा होता है, लेकिन browser की internal information दिखाने और बदलने की जरूरत के कारण इसे सामान्य web page से ज्यादा privileges मिलते हैं
    • WebUI frontend का JavaScript private APIs के जरिए browser के native C++ code से communicate कर सकता है
  • अगर WebUI में code execution संभव हो जाए, तो यह Chromium sandbox bypass तक पहुंच सकता है, इसलिए attackers को chrome:// page पर untrusted JavaScript चलाने से रोकना जरूरी है
  • उदाहरण के लिए, chrome://downloads में .exe download item par click करने से executable खुल सकता है, इसलिए Chromium जांचता है कि file open action वास्तव में user input से आया है या नहीं

enterprise policy testing feature का bypass

  • vulnerability research की शुरुआत Chromium के enterprise policy system से हुई
    • यह system कंपनी या स्कूल के device पर admin द्वारा कुछ settings force करने के लिए होता है
    • policies आम तौर पर Google account से जुड़ी होती हैं और Google management server से डाउनलोड की जाती हैं
  • policies को device policies और user policies में बांटा जाता है
    • device policies Chrome OS device की पूरी settings manage करती हैं
    • user policies किसी खास user या browser instance पर लागू होती हैं और सभी platforms पर उपलब्ध हैं
    • Linux में /etc/opt/chrome/policies में JSON file रखकर Google Chrome instance पर user policies लागू की जा सकती हैं, लेकिन इस directory में लिखने के लिए root privileges चाहिए
  • वर्तमान device पर लागू policies को chrome://policy WebUI में देखा जा सकता है
    • यह page applied policy list, policy service logs, और JSON export feature देता है
    • सामान्यतः इस page पर policies edit करने का कोई तरीका नहीं होता
  • Chrome v117 के Chrome Enterprise release notes में chrome://policy/test page का उल्लेख था, जो Beta, Dev, Canary channels में policy testing की अनुमति देता है
    • Chromium documentation में release notes के अलावा इस feature का कहीं और जिक्र नहीं था
    • इसे सामान्य रूप से enable करने के लिए undocumented PolicyTestPageEnabled policy चाहिए
    • यह policy न होने पर chrome://policy/test chrome://policy पर redirect हो जाता है

setLocalTestPolicies validation failure

  • chrome://policy/test का JavaScript code test policies सेट करने के लिए sendWithPromise('setLocalTestPolicies', ...) का उपयोग करता है
    • sendWithPromise() WebUI private API chrome.send() का wrapper है
    • यह call C++ handler function को request भेजती है, और handler browser के अंदर के काम कर सकता है
  • chrome://policy console से setLocalTestPolicies को सीधे कॉल करने पर शुरुआत में browser crash हुआ, और log में policy array की जरूरत का message दिखा
  • policy array का format सही करके AllowDinosaurEasterEgg जैसी user policy भेजी गई, तो feature को explicitly enable किए बिना भी arbitrary policy सेट हो गई
  • C++ side के HandleSetLocalTestPolicies handler ने सिर्फ local_test_provider की मौजूदगी जांची, यह नहीं देखा कि policy testing वास्तव में allowed है या नहीं
  • LocalTestPolicyProvider::CreateIfAllowed() IsPolicyTestingEnabled(nullptr, channel) को कॉल करता था
    • पहला argument pref_service null होने से PolicyTestPageEnabled check skip हो गया
    • बची हुई जांच सिर्फ यह थी कि release channel CANARY या DEFAULT है या नहीं
  • unbranded Chromium build में GOOGLE_CHROME_BRANDING code compile नहीं होता, इसलिए channel UNKNOWN रहता है
    • enum में UNKNOWN = 0, DEFAULT = UNKNOWN होने से Chromium और derived builds में channel check pass हो जाता है
    • branded Google Chrome stable build में release channel सही तरह set होता है, इसलिए यह bug stable Google Chrome में काम नहीं करता

Browser Switcher से shell command execution

  • arbitrary user policy सेट की जा सकने पर Chrome enterprise policies का Legacy Browser Support module sandbox escape path बन गया
  • Legacy Browser Support को Browser Switcher भी कहा जाता है, और इसे इस तरह design किया गया है कि जब user Chromium में किसी खास URL पर जाए तो alternative browser launch हो
    • यह Internet Explorer users को support करने के लिए बनाया गया feature था
    • इसका behavior policies से controlled होता है
  • AlternativeBrowserPath और AlternativeBrowserParameters policies को मिलाकर Chromium “alternative browser” के रूप में arbitrary shell command चला सकता था
    • ये Browser Switcher policies केवल Linux, macOS, और Windows पर मौजूद हैं
  • उदाहरण flow इस प्रकार है
    • BrowserSwitcherEnabled को true पर सेट करें
    • BrowserSwitcherUrlList में example.com डालें
    • Linux पर AlternativeBrowserPath को /bin/bash पर सेट करें
    • AlternativeBrowserParameters को ["-c", "xcalc # ${url}"] जैसा सेट करें
  • browser जब example.com पर जाता है, तो Browser Switcher सक्रिय हो जाता है और /bin/bash -c 'xcalc # https://example.com' जैसे command चलती है
    • ${url} replacement value को # के बाद रखकर shell comment बना दिया जाता है
  • chrome://policy में policies सेट करने के बाद window.open("https://example.com";) कॉल करने से केवल JavaScript के जरिए arbitrary shell command execution तक पहुंचा जा सकता था

DevTools extension API का bypass path

  • सिर्फ पिछले चरणों से victim को chrome://policy में malicious code browser console में paste करना पड़ता, इसलिए यह व्यावहारिक नहीं था
  • auto-execution path malicious Chrome extension के जरिए मिला
    • extension page में JavaScript inject कर सकती है, लेकिन privileged WebUI pages में JavaScript नहीं चल पाना चाहिए
  • page में JavaScript चलाने के लिए extension की चार मुख्य APIs थीं
    • chrome.scripting
    • Manifest v2 की chrome.tabs
    • chrome.debugger
    • chrome.devtools.inspectedWindow
  • जांच के लिए chrome.devtools.inspectedWindow चुना गया, क्योंकि यह अपेक्षाकृत कम hardened लग रहा था
    • chrome.devtools API इस्तेमाल करने वाली extension के manifest में devtools_page field होनी चाहिए
    • जब user DevTools खोलता है, तो वह page iframe में load होता है, और उसके भीतर chrome.devtools API इस्तेमाल की जा सकती है
  • David Erceg की पुरानी bug report में chrome.devtools.inspectedWindow.eval() के जरिए WebUI में code execution तक पहुंचने का मामला पहले से था
    • सामान्य रूप से inspected page के WebUI पर जाने पर DevTools API access disable हो जाना चाहिए
    • bypass का सार यह था कि Chrome API disable करने से पहले eval request भेज दी जाए, ताकि वह request WebUI page तक पहुंच जाए

inspectedWindow.reload() और about:blank की विशेषता

  • chrome.devtools.inspectedWindow.reload() भी injectedScript argument मिलने पर inspected page में JavaScript चला सकता है
  • WebUI द्वारा खोले गए about:blank page में inspectedWindow.reload() कॉल करने पर privileged page में JavaScript execution संभव था
    • about:blank URL खुद में खास नहीं है, लेकिन यह उसे खोलने वाले page के privileges और origin inherit करता है
    • chrome://settings द्वारा खोला गया about:blank page, chrome://settings origin वाला privileged page था
  • DevTools API disable करने वाला code inspected target का सिर्फ URL जांचता था, origin नहीं
    • URL सामान्य दिखे तब भी origin privileged हो सकता है
  • केवल about:blank path को सीधे exploit chain में इस्तेमाल करना कठिन था, क्योंकि chrome://policy about:blank popup नहीं खोलता
  • फिर भी कुछ स्थितियों में जहां inspectedWindow.eval() fail होता था, वहीं inspectedWindow.reload() chrome://settings में JavaScript चला देता था
    • इससे पता चलता है कि eval() में origin check जैसा अतिरिक्त guard था, जबकि reload() में वैसी सुरक्षा नहीं थी

race condition से crash-based method तक stabilization

  • पहली exploit chain में inspectedWindow.reload() कॉल को बार-बार दोहराया गया, ताकि inspected page के WebUI में जाने के तुरंत बाद और DevTools page द्वारा API disable करने से पहले की छोटी window को hit किया जा सके
    • यह इस धारणा पर आधारित था कि inspected page और DevTools page अलग processes में हैं
    • अगर chrome://policy navigation के क्षण और DevTools API disable होने के बीच reload() request पहुंच जाए, तो WebUI में code चल सकता था
  • यह तरीका काम करता था, लेकिन reliable नहीं था
    • tuning के बाद लगभग 70% success rate मिली
    • vulnerability गंभीर थी, लेकिन instability severity कम कर सकती थी
  • इसके बाद David Erceg के पुराने approach की तरह यह परखा गया कि tab crash के बाद pending debugger requests वाला behavior inspectedWindow.reload() पर भी लागू ho sakta hai ya nahin
  • debugger statement को लगातार दो बार trigger करने पर tab crash हो गया, और queue में बचा Page.reload request WebUI पर जाने के बाद execute हो सकता था
    • इससे race condition की जरूरत खत्म हो गई और यह 100% reliable हो गया
  • पहले के bug patch में Google ने crash के बाद pending debugger requests साफ करने का बदलाव किया था, लेकिन Page.reload request को exception के रूप में छोड़ दिया गया था
    • inspectedWindow.reload() internally Page.reload request भेजता है, इसलिए यह उसी exception से प्रभावित था
    • उस समय का patch यह नहीं रोक पाया कि Page.reload script execute कर सकता है
  • tab crash सिर्फ debugger method से ही नहीं, out-of-memory condition बनाकर भी संभव था, लेकिन अंतिम PoC में तेज debugger crash इस्तेमाल किया गया

अंतिम exploit chain और user interaction

  • अंतिम PoC इस क्रम में काम करता था
    • chrome.devtools.inspectedWindow.reload() vulnerability का उपयोग करके chrome://policy में JavaScript payload चलाया जाता था
    • payload sendWithPromise("setLocalTestPolicies", policy) कॉल करके user policies सेट करता था
    • BrowserSwitcherEnabled, BrowserSwitcherUrlList, AlternativeBrowserPath, AlternativeBrowserParameters सेट किए जाते थे
    • window.open() या page navigation से Browser Switcher trigger करके shell command चलाया जाता था
  • PoC में OS के अनुसार calculator launch command इस्तेमाल की गई
    • Windows: C:\Windows\System32\cmd.exe और calc.exe
    • Linux: /bin/bash और xcalc
    • macOS: /bin/bash और open -na Calculator
  • user interaction बस इतना था कि user DevTools खोल दे
    • example screen का “extension install error” user को DevTools खोलने के लिए trick करने का एक तरीका था
    • DevTools खुलते ही sandbox escape chain शुरू हो जाती थी

Google के fixes और CVE assignment

सार्वजनिक समयरेखा और सामग्री

  • timeline इस प्रकार है
    • 16 अप्रैल: test policies bug मिला
    • 29 अप्रैल: inspectedWindow.reload() race condition bug मिला
    • 1 मई: Google को bug report किया गया
    • 4 मई: Google ने इसे P1/S1 classify किया
    • 5 मई: inspected page crash से जुड़ा bug मिलने के बाद report update की गई
    • 6 मई: Google ने chain के हर हिस्से के लिए अलग bug report मांगी
    • 8 जुलाई: bug report को fixed के रूप में mark किया गया
    • 13 जुलाई: reward decision के लिए Chrome VRP panel को भेजा गया
    • 17 जुलाई: VRP panel ने $20,000 reward तय किया
    • 15 अक्टूबर: पूरी bug report public हुई
  • संबंधित मूल bug report crbug.com/338248595 पर देखी जा सकती है
  • vulnerability के हर हिस्से के PoC GitHub repository में public हैं
  • inspectedWindow.reload bug Chrome v45 तक पीछे जाकर काम करता था
  • जब undocumented, अधपके और unsafe features सभी users तक पहुंचा दिए जाते हैं, तो कई साधारण गलतियां मिलकर high severity vulnerability बन सकती हैं

1 टिप्पणियां

 
GN⁺ 2024-10-18
Hacker News की राय
  • कहा गया था कि पेज URL को ${url} से बदला जाता है, और कमांड को खराब होने से बचाने के लिए उसे # के बाद रखने पर वह comment बन जाता है — क्या इस policy में ऐसा कोई validation logic है कि URL को AlternativeBrowserParameters में कहीं पास होना चाहिए?

  • प्रोग्रामिंग, वेब डेवलपमेंट और साइबरसिक्योरिटी में रुचि रखने वाला एक हाई स्कूल छात्र — यह सच में प्रभावशाली है

    • तकनीकी प्रतिभा, धैर्य, documentation और communication skills — सब शानदार हैं
      responsible disclosure process तक का पालन करने वाली पेशेवर नैतिकता भी कमाल की है; आगे चलकर यह व्यक्ति बहुत बड़ा करेगा
  • यह शानदार लेख और काम था, और खोज पर खोज जुड़ने के साथ उत्साह बढ़ता गया — ऐसा लगा मानो मैं भी उस प्रक्रिया के साथ चल रहा हूँ
    इनाम भी पूरी तरह deserve करता है

  • vulnerability chaining की प्रक्रिया भी साफ-सुथरी थी और लेखन भी बेहतरीन। vulnerable code कैसे काम करता है, इसे तोड़कर दिखाना भी बहुत अच्छा लगा
    “फिर से कोशिश करने के लिए F12 दबाएँ” जैसी साधारण ट्रिक्स हर बार प्रभावित करती हैं — सच में शरारती अंदाज़ है

    • मैं Missouri में रहता हूँ; मैंने एक बार F12 दबाया था और गवर्नर मुझे गिरफ्तार करना चाहते थे
  • इससे मुझे वह पुराना मामला याद आ गया जब इसी API से Chrome OS के crosh shell को debug करके OS protections को bypass किया गया था, और developer device पर root access तक मिल गया था। वह CVE-2014-3172 था
    लेकिन इस लेख के लेखक को इससे कहीं कठिन बाधाओं को bypass करना पड़ा, और यह सच में शानदार काम है

  • रात बहुत हो चुकी है, इसलिए WebUI validation में क्या टूटा, उसमें गहराई से जाना मुश्किल है, लेकिन यह अच्छा लगा कि लेखक ने अंत तक जाकर इसे समझा
    जिन चीज़ों को हम ship करते हैं, उनकी toolchain पर शक करना और उस पर भरोसा न करना काफ़ी standard mindset है, लेकिन साथ ही हम Google या Microsoft जैसी बड़ी कंपनियों के जादुई रूप से सुविधाजनक development tools पर बहुत ज़्यादा भरोसा करते हैं। आखिरकार Chromium या VSCode के अंदर क्या छिपा है, इसकी चिंता करने के बजाय मैं अपना code लिखना और test करना चाहता हूँ

  • यह उन बेहतरीन लेखों में से एक है जो मैंने पढ़े हैं
    सच में बहुत ही चतुर tracking work था

  • browser code खंगालकर यहाँ तक पहुँचने की मेहनत कमाल की है, और लेख भी बहुत दिलचस्प और विस्तारपूर्ण है

  • हाई स्कूल छात्र? वाह, सच में कमाल है

  • Chromium project ने chrome://net-internals को यह कहकर हटा दिया कि वह बहुत जटिल था, और उसकी जगह आधा-अधूरा JSON editing support वाला chrome://policy जोड़ दिया