Kaan Kozan tarafından yazılmıştır.
Hoşgeldiniz, bu yazımda Dom Xss hakkında bir anlatım yapacağım. Umarım anlaşılması açısından kolay ve öğrenmek isteyenlere yararlı olur.
Client Side bir bileşen olan Dom Xss, güvenli olmayan Javascript tabanlı dinamik kod jenerasyonları tarafından oluşabilir. Unsafe string interpolation olarak adlandırılmakta olan birtakım sebeplerden kaynaklanarak tarayıcı sisteminde bazı oluşumlarda zafiyet gösterebilmektedir.
JavaScript veya VBScript ayrıştırıcısı, komut kodlarının ayrıştırılarak çalıştırılması ile ilgilidir. HTML, HTML attribute, URL, ve CSS contexts bu bağlamda zafiyetden sorumlu olabilir.
Dom Xss atakları her zaman tarayıcı tarafında execute edilir. Yani Dom Based Xss istemci tarafındaki kodun beklenmedik çalışmasından oluşabilir. Dom Xss ancak real-time olarak tespit edilebilen, sunucu taraflı filtrelemelerin önemli olmadığı bir türdür.
Diğer Cross-Site Scripting türlerindeki gibi filtreleme yapmak, Web Application taraflı güvenlik duvarları, istek doğrulama çerçeveleri zafiyetin oluşumu için herhangi bir engel teşkil etmez.
Dom Xss zafiyetini kaldırabilmemiz için büyük çaplı değişiklikler yapmamız gerekebilir.
Dom Xss’in önüne geçebilmek için HTML Encoding ( Ayrıştırması ) ve daha sonrasında ise, girilen tüm inputlarda Javascript ayrıştırması yapılmalıdır.
Javascript, international standard (ECMAScript) tabanlı bir dil olduğundan bazı Hex ayrıştırmaları gibi escape (kaçış) karakterlerine izin vermektedir. Bu durumda Cross-Site Scripting zafiyetinin oluşumuna dikkat edilmelidir.
Dom Xss siteler arası komut kullanımını ortaya çıkarabilir. Dom Based Xss, document.referrer, document.url ve document.location benzeri DOM belgelerinin değiştirilmesi tetikleyebilir.
Saldırgan belirlenen dokümasyon erişimleri ile bunları manipüle edebilir. Aynı zamanda eval(), document.write or innerHTML, methodlarının zararlı kullanılabilmesi sayesinde, zafiyet kullanılabilir hale gelmektedir.
Not: Normalde document.write bileşeninin sadece test amaçlı kullanılması önerilmektedir.
Dom Xss kaynağı bakımından Javascript ile yoğun ölçüde dinamik kod incelemeleri gerektirir. Aynı zamanda dilin yapısı bakımından (Javascript); false positive eğilimli, complex ve kaynak dayanımlı olmasından bu durum bazı zamanlar oldukça zordur.
Dom Based Xss, javascript kodunun tam zamanlı ayrıştırmalar esnasında yorumlanabilme açısından etki edebilmesini gerektirir.
Bu durumda Javascript motoru, JIT compleksi nedeniyle debug amacıyla oluşturulmuş API’ler kullanılması eval kullanımlarında breakpoint oluşturulabilmesi açısından önemlidir. Daha iyi anlayabilmemiz için birkaç örnek üzerinden gidelim.
1) DOM XSS in
innerHTML elementinin kullanımında pek güvenilir olamayabileceğini biliyoruz. Sebebimiz burada her defasında bizim innerHTML’yi kullanıldığı yerde HTML ayrıştırılmalı, DOM Belgesi oluşturulması ve düzenlenmelidir.
İşte tam olarak bu aşamada innerHTML kullanılan her yerde birçok, belki binlerce block değerinde <div> elementlerinin tekrardan parse edilmesine sebep olabilmektedir.
Bu parse edilme işleminde eğer istemci tabanlı bazı modifikasyonlar yapılırsa, yeniden innerHTML ile oluşturulan benzer Dom Dokümasyonu bazı değişiklikler ile oluşturulabilir.
Not: Tabi ki güvensiz olabilse de kllanılması her durumda o kadar zararlı olmayabilir.
İşte PortSwigger’in bu Lab’ında sizlerle bu elementin sebep olabileceği bazı durumlara ve bunun sonucunda neler yapılabileceğine bakacağız.
PortSwigger Lab of location.search
İlk olarak challange bize bir blog sayfası veriyor. Biraz daha incelediğimizde bir search elementi görebiliyoruz. Tam bu kısımda aslında Dom Xss baş gösteriyor. Hadi innerHTML ve peşinden gelen DOM Xss senaryosunu inceleyelim.
Dom XSS location.search
Gördüğünüz gibi herhangi bir arama yaptım ve search yaparken basit olarak location.search etiketli bir kullanım gördüm.
innerHTML ile Dom XSS
Bunu Burpsuite ile Reapter’dan incelediğimde zafiyeti trigger eden (tetikleyen) fonksiyonu ve elementi görebiliyorum. Peki bu fonksiyonumuz ne yapıyor?
function doSearchQuery(query) {
document.getElementById('searchMessage').innerHTML = query;
}
var query = (new URLSearchParams(window.location.search)).get('search');
if(query) {
doSearchQuery(query);
Fonksiyonumuz basitçe doSearchQuery isimli bir olay döndürüyor. Bu işlemde SearchBox’dan ‘searchMessage’ id’sini kullanmakta olan bir veri alıyor ve aldığı veriyi inner.HTML ile işleyerek bir query oluşturuyor.
İşte tüm zafiyet burada inner.HTML kullanarak yeni bir DOM Belgesi oluşturmasında karşımıza çıkıyor. Tabi bu fonksiyondan almış olduğu query ile window.location isimli bir obje yardımıyla bir URL oluşturuyor.
Tam olarak zafiyet burada parse işleminde tipik olarak window.location objesiyle ulaşılabilir.
Hadi bir payload deneyelim. Bu payload’ımızda bir img oluşturalım, çünkü bizim amacımız en basitiyle DOM Dokümasyonuna etki etmek. Daha sonrasında bu img tag’ı için src özniteliğini 1 veya x benzeri belirsiz veriler ile işleyelim. Daha sonrasında onerror kullanarak bir sorun oluşması durumunda alert() etkmesini söyleyelim.
search.location Dom Basec Xss Request
Gördüğümüz gibi başarılı bir şekilde trigger edebildik. Bu aşamada birçok şey kritik bir biçimde mümkün.
Exploiting DOM XSS Alert
Not: Bazı senaryolarda RedirectURI gibi parametrelerde zafiyet kullanılabilmektedir.
Basit bir örnekle anladığımıza göre hadi birde PostMessage bu bağlamda ne kadar etkili inceleyelim.
Gördüğünüz gibi bu örnek de birçok şekilde deneme yapabileceğimiz Firinge Range testing ortamını kullanacağız. Oldukça güzel ve deneme yapılması için birebir bir ortam sunan bir platform.
Firinge Range eval Dom XSS
Ben eval örneğini seçtim. Gördüğünüz üzere örneğe eriştiğimizde boş bir sayfa ile karşılaşıyoruz.
Empty Page – eval
Bu örneğimizde aklımıza gelebileceği üzere PostMessage ile iframe kullanabilir durumdayız. Hadi sizlerle sebebini ve zafiyeti inceleyelim. Ben bu örneğimizde Google Devtools kullanıyor olacağım. Bilmeyenler için Dev Tools’dan biraz bahsedecek olursak;
Google Devtools >> Google Devtools temel olarak developerlar için geliştirilen bir araçtır. Bu araç sayesinde log, performans, network ve cookies, requests – responses gibi birçok bileşeni gerçek zamanlı olarak inceleyebilir, denemeler yapabiliriz. Detaylı bilgiye buradan erişebilirsiniz; https://developer.chrome.com/docs/devtools/
Not: Aslında Google Devtool’u tercih etmekteyim fakat sizler Firefox Devtool üzerinden gitmekte sorun yaşamayacaksınız.
Gördüğünüz üzere İnspect ederek Google Devtools’dan Network kısmına geldim ve eval isimli bir Request’in gittiğini gördüm.
Google DevTools eval Request
Bu aşamada bu Request bize ulaşan bir Response içerdiğinden bunu incelemeye ve gelen Source Code’u analiz etmeye karar verdim.
[IMG alt="
var postMessageHandler = function(msg) {
var content = msg.data;
var msgObj = eval(content);
if (msgObj.isActive) {
document.write("]https://pwnlab.me/wp-content/uploads/2021/04/9-1024x299.jpg[/IMG]
Evet kodumuza kısa bir bakış attıktan sonra windows.object üzerinden bir EventListener oluşturarak, işleme aldığı postMessageHandler, message, false değişkenlerini sunduğunu görebiliyoruz.
İlk olarak debug özelliğimiz ile debugger’imize değişimi daha rahat takip edebilmek için 7 ve 9 satırlarında duraklamasını söyleyelim.
Hadi bizim işlemde ana karakterimiz olan Content msg.data verisine bir etkileşim değeri verelim. Ben örnek olarak “message” datasını atıyorum ve gördüğünüz şekilde değiştiriyorum.
Content-msg.data
window.postMessage('message', '*')
content = message
Ardından msg.data içeriği olan Content değerine bir Javascript etkileşimi verelim. Verdiğimiz etkileşimde de alert() kullanmayı amaçlayalım. Ben document.domain özniteliğini pop-up olarak vermesini istedim.
Alert – msg.data
Gördüğünüz gibi basit bir şekilde buradaki etkileşimi anladık, tabi biz burada alert’i başta message yerine koyabilirdik fakat ben anlaşılırlık açısından böyle kullanma taraftarıyım. Hadi anladığımıza göre target için biraz daha komplike bir şeyler yapımına geçelim birde.
Bir iframe oluşturarak Dom Xss’i trigger etmeyi planlıyoruz. Bunun için bir kod hazırlayalım. Bu kod’da iframe için bir id vererek bir EventListener oluşturalım ve bununla PostMessage verisini msg.data ile sunalım. İşte bu bize tam olarak bir olası senaryo verecektir.
Dom XSS Content via iframe
Evet, yazı boyunca çoğu durumda Cross-Site Scripting için en tehlikeli tür denen Dom XSS’den bahsettik, umarım anlaşılır ve yararlı olmuştur. Hatam olduysa bize ulaşmayı unutmayın!
Anlatacaklarım bu kadardı. Okuduğunuz için teşekkürler, esenlikler diliyorum.
[TR] DOM XSS ile Post Message Fuzzing
Hoşgeldiniz, bu yazımda Dom Xss hakkında bir anlatım yapacağım. Umarım anlaşılması açısından kolay ve öğrenmek isteyenlere yararlı olur.
Dom Xss Neden Kaynaklanır?
Client Side bir bileşen olan Dom Xss, güvenli olmayan Javascript tabanlı dinamik kod jenerasyonları tarafından oluşabilir. Unsafe string interpolation olarak adlandırılmakta olan birtakım sebeplerden kaynaklanarak tarayıcı sisteminde bazı oluşumlarda zafiyet gösterebilmektedir.
JavaScript veya VBScript ayrıştırıcısı, komut kodlarının ayrıştırılarak çalıştırılması ile ilgilidir. HTML, HTML attribute, URL, ve CSS contexts bu bağlamda zafiyetden sorumlu olabilir.
Dom Xss atakları her zaman tarayıcı tarafında execute edilir. Yani Dom Based Xss istemci tarafındaki kodun beklenmedik çalışmasından oluşabilir. Dom Xss ancak real-time olarak tespit edilebilen, sunucu taraflı filtrelemelerin önemli olmadığı bir türdür.
DOM Xss Nasıl Engellenir?
Diğer Cross-Site Scripting türlerindeki gibi filtreleme yapmak, Web Application taraflı güvenlik duvarları, istek doğrulama çerçeveleri zafiyetin oluşumu için herhangi bir engel teşkil etmez.
Dom Xss zafiyetini kaldırabilmemiz için büyük çaplı değişiklikler yapmamız gerekebilir.
Dom Xss’in önüne geçebilmek için HTML Encoding ( Ayrıştırması ) ve daha sonrasında ise, girilen tüm inputlarda Javascript ayrıştırması yapılmalıdır.
Javascript, international standard (ECMAScript) tabanlı bir dil olduğundan bazı Hex ayrıştırmaları gibi escape (kaçış) karakterlerine izin vermektedir. Bu durumda Cross-Site Scripting zafiyetinin oluşumuna dikkat edilmelidir.
Dom Xss siteler arası komut kullanımını ortaya çıkarabilir. Dom Based Xss, document.referrer, document.url ve document.location benzeri DOM belgelerinin değiştirilmesi tetikleyebilir.
Saldırgan belirlenen dokümasyon erişimleri ile bunları manipüle edebilir. Aynı zamanda eval(), document.write or innerHTML, methodlarının zararlı kullanılabilmesi sayesinde, zafiyet kullanılabilir hale gelmektedir.
Not: Normalde document.write bileşeninin sadece test amaçlı kullanılması önerilmektedir.
Dom Xss Nasıl Tespit Edilebilir?
Dom Xss kaynağı bakımından Javascript ile yoğun ölçüde dinamik kod incelemeleri gerektirir. Aynı zamanda dilin yapısı bakımından (Javascript); false positive eğilimli, complex ve kaynak dayanımlı olmasından bu durum bazı zamanlar oldukça zordur.
Dom Based Xss, javascript kodunun tam zamanlı ayrıştırmalar esnasında yorumlanabilme açısından etki edebilmesini gerektirir.
Bu durumda Javascript motoru, JIT compleksi nedeniyle debug amacıyla oluşturulmuş API’ler kullanılması eval kullanımlarında breakpoint oluşturulabilmesi açısından önemlidir. Daha iyi anlayabilmemiz için birkaç örnek üzerinden gidelim.
1) DOM XSS in innerHTML
sink using source location.search
innerHTML elementinin kullanımında pek güvenilir olamayabileceğini biliyoruz. Sebebimiz burada her defasında bizim innerHTML’yi kullanıldığı yerde HTML ayrıştırılmalı, DOM Belgesi oluşturulması ve düzenlenmelidir.
İşte tam olarak bu aşamada innerHTML kullanılan her yerde birçok, belki binlerce block değerinde <div> elementlerinin tekrardan parse edilmesine sebep olabilmektedir.
Bu parse edilme işleminde eğer istemci tabanlı bazı modifikasyonlar yapılırsa, yeniden innerHTML ile oluşturulan benzer Dom Dokümasyonu bazı değişiklikler ile oluşturulabilir.
Not: Tabi ki güvensiz olabilse de kllanılması her durumda o kadar zararlı olmayabilir.
İşte PortSwigger’in bu Lab’ında sizlerle bu elementin sebep olabileceği bazı durumlara ve bunun sonucunda neler yapılabileceğine bakacağız.
PortSwigger Lab of location.search
İlk olarak challange bize bir blog sayfası veriyor. Biraz daha incelediğimizde bir search elementi görebiliyoruz. Tam bu kısımda aslında Dom Xss baş gösteriyor. Hadi innerHTML ve peşinden gelen DOM Xss senaryosunu inceleyelim.
Dom XSS location.search
Gördüğünüz gibi herhangi bir arama yaptım ve search yaparken basit olarak location.search etiketli bir kullanım gördüm.
innerHTML ile Dom XSS
Bunu Burpsuite ile Reapter’dan incelediğimde zafiyeti trigger eden (tetikleyen) fonksiyonu ve elementi görebiliyorum. Peki bu fonksiyonumuz ne yapıyor?
function doSearchQuery(query) {
document.getElementById('searchMessage').innerHTML = query;
}
var query = (new URLSearchParams(window.location.search)).get('search');
if(query) {
doSearchQuery(query);
Fonksiyonumuz basitçe doSearchQuery isimli bir olay döndürüyor. Bu işlemde SearchBox’dan ‘searchMessage’ id’sini kullanmakta olan bir veri alıyor ve aldığı veriyi inner.HTML ile işleyerek bir query oluşturuyor.
İşte tüm zafiyet burada inner.HTML kullanarak yeni bir DOM Belgesi oluşturmasında karşımıza çıkıyor. Tabi bu fonksiyondan almış olduğu query ile window.location isimli bir obje yardımıyla bir URL oluşturuyor.
Tam olarak zafiyet burada parse işleminde tipik olarak window.location objesiyle ulaşılabilir.
Hadi bir payload deneyelim. Bu payload’ımızda bir img oluşturalım, çünkü bizim amacımız en basitiyle DOM Dokümasyonuna etki etmek. Daha sonrasında bu img tag’ı için src özniteliğini 1 veya x benzeri belirsiz veriler ile işleyelim. Daha sonrasında onerror kullanarak bir sorun oluşması durumunda alert() etkmesini söyleyelim.
search.location Dom Basec Xss Request
Gördüğümüz gibi başarılı bir şekilde trigger edebildik. Bu aşamada birçok şey kritik bir biçimde mümkün.
Exploiting DOM XSS Alert
Not: Bazı senaryolarda RedirectURI gibi parametrelerde zafiyet kullanılabilmektedir.
Basit bir örnekle anladığımıza göre hadi birde PostMessage bu bağlamda ne kadar etkili inceleyelim.
2) Firinge Range / PostMessage – eval – Dom XSS
Gördüğünüz gibi bu örnek de birçok şekilde deneme yapabileceğimiz Firinge Range testing ortamını kullanacağız. Oldukça güzel ve deneme yapılması için birebir bir ortam sunan bir platform.
Firinge Range eval Dom XSS
Ben eval örneğini seçtim. Gördüğünüz üzere örneğe eriştiğimizde boş bir sayfa ile karşılaşıyoruz.
Empty Page – eval
Bu örneğimizde aklımıza gelebileceği üzere PostMessage ile iframe kullanabilir durumdayız. Hadi sizlerle sebebini ve zafiyeti inceleyelim. Ben bu örneğimizde Google Devtools kullanıyor olacağım. Bilmeyenler için Dev Tools’dan biraz bahsedecek olursak;
Google Devtools >> Google Devtools temel olarak developerlar için geliştirilen bir araçtır. Bu araç sayesinde log, performans, network ve cookies, requests – responses gibi birçok bileşeni gerçek zamanlı olarak inceleyebilir, denemeler yapabiliriz. Detaylı bilgiye buradan erişebilirsiniz; https://developer.chrome.com/docs/devtools/
Not: Aslında Google Devtool’u tercih etmekteyim fakat sizler Firefox Devtool üzerinden gitmekte sorun yaşamayacaksınız.
Gördüğünüz üzere İnspect ederek Google Devtools’dan Network kısmına geldim ve eval isimli bir Request’in gittiğini gördüm.
Google DevTools eval Request
Bu aşamada bu Request bize ulaşan bir Response içerdiğinden bunu incelemeye ve gelen Source Code’u analiz etmeye karar verdim.
[IMG alt="
var postMessageHandler = function(msg) {
var content = msg.data;
var msgObj = eval(content);
if (msgObj.isActive) {
document.write("]https://pwnlab.me/wp-content/uploads/2021/04/9-1024x299.jpg[/IMG]
Evet kodumuza kısa bir bakış attıktan sonra windows.object üzerinden bir EventListener oluşturarak, işleme aldığı postMessageHandler, message, false değişkenlerini sunduğunu görebiliyoruz.
İlk olarak debug özelliğimiz ile debugger’imize değişimi daha rahat takip edebilmek için 7 ve 9 satırlarında duraklamasını söyleyelim.
Hadi bizim işlemde ana karakterimiz olan Content msg.data verisine bir etkileşim değeri verelim. Ben örnek olarak “message” datasını atıyorum ve gördüğünüz şekilde değiştiriyorum.
Content-msg.data
window.postMessage('message', '*')
content = message
Ardından msg.data içeriği olan Content değerine bir Javascript etkileşimi verelim. Verdiğimiz etkileşimde de alert() kullanmayı amaçlayalım. Ben document.domain özniteliğini pop-up olarak vermesini istedim.
Alert – msg.data
Gördüğünüz gibi basit bir şekilde buradaki etkileşimi anladık, tabi biz burada alert’i başta message yerine koyabilirdik fakat ben anlaşılırlık açısından böyle kullanma taraftarıyım. Hadi anladığımıza göre target için biraz daha komplike bir şeyler yapımına geçelim birde.
Bir iframe oluşturarak Dom Xss’i trigger etmeyi planlıyoruz. Bunun için bir kod hazırlayalım. Bu kod’da iframe için bir id vererek bir EventListener oluşturalım ve bununla PostMessage verisini msg.data ile sunalım. İşte bu bize tam olarak bir olası senaryo verecektir.
Dom XSS Content via iframe
Evet, yazı boyunca çoğu durumda Cross-Site Scripting için en tehlikeli tür denen Dom XSS’den bahsettik, umarım anlaşılır ve yararlı olmuştur. Hatam olduysa bize ulaşmayı unutmayın!
Anlatacaklarım bu kadardı. Okuduğunuz için teşekkürler, esenlikler diliyorum.
Moderatör tarafında düzenlendi: