GitHub private pages bug bounty से 35,000 डॉलर कमाना
(robertchen.cc)एक 12वीं कक्षा के छात्र की कहानी, जिसने Covid के दौरान खाली समय में bug bounty hunting की और GitHub के private pages bug bounty से 35,000 डॉलर कमाए.
उसने GitHub के private pages bug bounty में रिपोर्ट किया, और इसमें दो CTF बोनस थे.
-
10,000 डॉलर: बिना user interaction के
flag.private-org.github.ioसे flag पढ़ना. अगरprivate-orgorganization के बाहर का कोई account यह flag पढ़ सके, तो 5,000 डॉलर का अतिरिक्त बोनस मिलता है. -
5,000 डॉलर: user interaction के जरिए
flag.private-org.github.ioसे flag पढ़ना.
authentication flow
GitHub pages एक अलग domain github.io पर host होते हैं, इसलिए github.com के authentication cookies private pages server तक नहीं भेजे जाते. इसलिए private page authentication, github.com के साथ अतिरिक्त integration के बिना, user की पहचान नहीं जान सकता. इसी वजह से GitHub ने एक custom authentication flow बनाया.
-
private page पर जाने पर server
__Host-gh_pages_tokencookie की मौजूदगी जांचता है. -
अगर cookie नहीं है या सही नहीं है, तो private page server
https://github.com/loginपर redirect करेगा. -
यह redirect
__Host-gh_pages_sessioncookie में nonce भी सेट करता है.- यह cookie __Host- cookie prefix का उपयोग करती है, इसलिए host domain के अलावा कहीं और से इसे JavaScript द्वारा सेट करने से रोका जाता है.
-
/login/pages/auth?nonce=&page_id=&path=पर redirect करता है. -
यहां
tokenparameter सेhttps://pages-auth.github.com/redirectको भेजने के लिए एक temporary authentication cookie बनाई जाती है. -
/redirecthttps://repo.org.github.io/__/authपर forward करता है. -
यह अंतिम endpoint
repo.org.github.iodomain पर authentication cookies__Host-gh_pages_tokenऔर__Host-gh_pages_idसेट करता है. -
यहां पहले सेट किए गए
__Host-gh_pages_sessionकेnonceकी भी जांच होती है.
मूल request path और page ID क्रमशः query parameters path, page_id में संग्रहीत होते हैं, और nonce भी nonce parameter में संग्रहीत होता है.
exploitation
CRLF return
-
पहली vulnerability
https://repo.org.github.io/__/authकेpage_idparameter में CRLF injection थी. -
पता चला कि
page_idparsing whitespace को ignore करती है, और यह value सीधेSet-Cookieheader में सेट हो जाती है. -
पारंपरिक CRLF injection से parsing को तोड़ा जा सकता है, लेकिन उसका कोई और प्रभाव नहीं था.
-
क्योंकि
Location:header,Set-Cookieheader के बाद जुड़ता है, इसलिए 302 redirect होने के बावजूद Location header ignore हो जाता है और body render होती है.
attack
-
GitHub enterprise code देखकर पता चला कि private page server openresty nginx में implement किया गया था.
-
null byte जोड़कर XSS सफल किया गया. यह null byte body की शुरुआत में आना चाहिए, इसलिए header injection attack नहीं किया जा सकता.
-
इससे private page domain पर arbitrary JavaScript code execute करना संभव हो गया.
-
अब बस nonce को bypass करने का तरीका ढूंढना बाकी था.
nonce bypass
-
जांच में पता चला कि एक ही organization के sibling private pages एक-दूसरे के लिए cookies सेट कर सकते हैं.
-
private-org.github.ioपर सेट की गई cookiesprivate-page.private-org.github.ioतक भेजी जाती हैं. -
अगर
__Host-prefix protection को bypass किया जा सके, तो nonce को आसानी से bypass किया जा सकता है. -
सभी browsers इसे support नहीं करते, और IE
__Host-prefix को support नहीं करता. -
लेकिन इससे बेहतर तरीका खोजते हुए एक दिलचस्प idea आया.
-
cookies uppercase और lowercase को कैसे handle करती हैं, यह देखने पर पता चला कि
__HOSTऔर__Hostको अलग तरह से treat किया जाता है, और GitHub private pages cookies parse करते समय uppercase को ignore करते हैं. -
इससे JavaScript के जरिए nonce सेट करना संभव हो गया.
-
इसके लिए 5,000 डॉलर का बोनस मिला.
cache pollution
-
/__/auth?endpoint का response spoofedpage_idके integer value के आधार पर cache किया जाता है. -
इससे XSS payload के जरिए cache pollution सफल होने पर बिना interaction वाले users भी प्रभावित होते हैं.
-
अगर attacker
unprivileged.org.github.ioपर हमला करके authentication को poison कर दे, तो XSS payload cache हो जाती है. -
क्योंकि cookies parent domain
org.github.ioपर shared होती हैं, attackerprivileged.org.github.ioपर भी हमला कर सकता है.
public private pages
-
15,000 डॉलर का बोनस पाने के लिए यह ज़रूरी था कि organization से बाहर का user भी इस attack को कर सके.
-
public repository पर private pages सेट करने वाली एक misconfiguration के जरिए यह attack संभव था.
- मतलब, पहले private repo में pages बनाना और बाद में repository को public कर देना.
-
इस misconfiguration वाली private page सभी users के लिए authentication flow शुरू कर देती है और organization के बाहर के users को read access दे देती है.
अभी कोई टिप्पणी नहीं है.