Merhaba, bugün sizlere bakış açınızı derinleştirecek ve neyin nasıl işlediğini göreceğiniz bir konu üzerine konuşacağız; XSS'in sistem manipülesi
Bu yazımızda XSS'e dair bilinen hiçbir klasik bilgiye değinmeyeceğiz. Sistemin nasıl çalıştığını ve scriptlerin waf'ı , browser'ı , frontend'i nasıl manipüle ettiği üzerine konuşacağız.
Bu yazıda başlıca şu sorulara cevap bulacaksınız:
1-Payload yazıldıktan sonra arka planda neler oluyor?
2- Sistem payload'ı neden tanıyamıyor?
3-Neden her payload sistemi manipüle edemiyor?
4- Her payload her browser'da çalışır mı?
5-Backend'in,waf'ın , frontend'in yaptığı hatalar nelerdir?
6- Xss genel işleyiş iskeleti/ Search'ten alerte yolculuk
Gibi bir çok soruya cevap bulacaksınız inşallah.

Bismillah
Bir web sitesi nasıl tasarlanır ve backend XSS için nerde hata yapar.
Bana göre yazının bu kısmı işin en önemli kısmı. Sitenin nasıl tasarlandığını ve tasarımcıların nerede hata yapabileceğini bilmek o siteye nasıl saldıracağını bilmektir. Düşmanını tanımayan zafer elde edemez.

Uygulamanın davranışı frontend (JS) + backend logic birlikte belirler. Burada sitenin akışı , nasıl korunacağı, nasıl davranacağını, gelen istekleri nasıl karşılaması gerektiği belirlenir. Backend developer işte burada tüm hünerini gösterir. Eğer bu kısım iyi yapılandırılmazsa tüm veri tabanı çökertilip sistem komple ele geçirilebilir.
Backend XSS için nasıl önlemler alıyor?
Backend'in yaptığı şey kullanıcıdan gelen hiçbir veriyi tarayıcıda kod olarak işlenmemesini sağlaktır.
Bunu da veriyi uygun bir şekilde contexte uygun escape ederek yapar.
WAF ile backendin XSS'i engelleme mantığını karıştırmamak gerekiyor yoksa sistemi anlayamayız.
WAF yalnızca isteği yüzeysel olarak filtereler ancak asıl güvenlik developer tarafından yapılır.
Senin payload'ın waf'ı geçerse eğer sistem doğru contexte escape ederse yine de çalışmaz, alert vermez.
Buradaki kritik nokta şudur: Sistem kodu tamamen reddetmez bunun yerine kullanıcı girdisini kod olarak değil metin olarak işleyecek şekilde tasarlanır.
Escape detayı yazının devamında..
ÖNEMLİ BİLGİ: Backend XSS'i engellemez Backend, browser'a giden verinin formatını kontrol eder
Peki developer bunu her subdomaine mi yapar?
Sistemde 1000'den fazla subdomain var hepsinde tek tek bunu yapmış mıdır yoksa gözden kaçılan noktalar var mıdır?
Backend dışarıdan kod kabul etmemeyi nasıl sağlıyor?
1- Dışarıdan harf ve rakam dışında veri kabul etmek
<script>alert(BUGHANE)</script>
Bunu kabul etmez çünkü < / ( ) gibi semboller kabul edilmiyor.
Bu payload'ı encode ederseniz sistem manipüle edilebilir.
PHNjcmlwdD5hbGVydChCVUdIQU5FKTwvc2NyaXB0Pg
Bu , Payload'ın base64 ile encode edildiği çıktısıdır. Bu çıktı sadece rakam ve harflerden oluşuyor. Sistem sadece harf ve rakam kabul et kuralı üzerine inşa edildiyse o sistemde XSS zafiyeti meydana gelir. Bazen birden fazla kez encode etmek gerekebilir.
NOT:
Encode edilmiş payload'lar, eğer uygulama tarafından decode edilirse veya farklı bir şekilde işlenirse anlam kazanır. Tek başına encode etmek XSS oluşturmaz.
2- <SCRİPT> geldiyse engelle kuralı
Özellikle eski sistemlerde <script> kabul etmeme kuralı vardı. Bu sade kural çok basit bir şekilde manipüle edilebilir.
<scr<script>ipt>
ile kolayca bypass edilebilir.
<script><script>alert()</script>
Burda içiçe iki scriptin olması bazen waf'ı yanlış analize götürüp filteri kandırabiliyor.
Yapılan şey şu oluyor: ikinci script HTML parser tarafından tag olarak değil, script içeriği olarak görülür ve XSS meydana gelir.
Not: Burdaki amaç ise browser'ı kandırmak değil filter'ı kandırmak.
3- Developer ESCAPE'İ Kapatmamış mı?
Escape anlattığımız gibi dışarıdan gelen kodları metine çevirmedir.
Escape açık kalmış ise dışarıdan search kısmına atacağınız scirpt alert verebilir. Bugbounty dünyasında en çok bulunan XSS de bu eksiklik yüzünden bulunuyor.
kısacası escape dışarıdan gelen her şeyi text olarak kabul edilip edilmemedir.
Escape yoksa: <div><script>alert(1)</script></div>
tarayıcı bunu HTML kodu olarak kabul eder .
Escape varsa: <div><script>alert(1)</script></div>
tarayıcı bunu metin olarak kabul eder ve bu veri HTML'de işlemez
Escape varsa senin payloadı'ı nasıl algılıyor aradaki farkı görebiliyor musun?

Dehşet bir görsel..
4-JSON içinde HTML olması tek başına XSS değildir
{ "name": "Zeki" }
{ "comment": "<img src=x onerror=alert(1)>" }
Burada mesele şu: Bu veri frontend tarafında nasıl kullanılıyor?
Eğer veri DOM tarafında şu şekilde basılırsa XSS meydana gelir
div.innerHTML = response.comment;
HTML içerisindeki veri tek başına XSS olamaz lakin XSS'e giden yolu verir.
NOT: Normalde olması gereken şey frontend'in texti innerHTML olarak değil innerTEXT ya da textContent olarak işlemeli
div.textContent = response.comment;
JSON içinde html dönüp dönmediğini nasıl anlarız
1.Sitede sağ tık yap(ya da f12)
2.inceleye bas
3.network sekmesine gel
4.sayfayı yenile
5.XHR /FETCH kısımlarına bak
Ordan bir request'e tıkla ve response kısmına gel
çıkan sonuç:
{ "username": "zeki", "comment": "<img src=x onerror=alert(1)>" }
gibi bir veri varsa burda şunu anla : HTML string barındırıyor ve eğer frontend
innerHTML Kullanmışsa işte o zaman veri HTML dönüşür ve içerisindeki string XSS olarak patlar.
<img src=x onerror=alert(1)> bunu input'a yaz ve çıkan sonucu incele
<img…> yazı olarak görünse ESCAPE VAR
Hiç görünmese demek render yok
Burada ben f12'ye bastım Network kısmına geldim ordan fetch kısmı istediğim isteğe tıklayınca zaten response kısmı önüme geliyor.

Eğer response içerisinde;
{ "comment": "<img src=x onerror=alert(1)>" }
gibi bir alert mevzusu görürsen durma devam et yüksek ihtimal XSS var.
bu img alert'i nerede render ediliyor onu bul.
CTRL+F YAP alert içindeki yazıyı ara ve hedefe git.
Sadece response kısmına bakma ELEMENTS KISMINA DA BAK
Orada şunları filter kısmında şunları aratabilirsin:
payload
username
comment
Şimdi sana çok kritik bir şey gösterecem. Buna dikkat et.
Source sekmesine gel. Orada şunları arayacağız:
innerHTML document.write insertAdjacentHTML
Özellikle innerHTML kısmını sana biraz anlatmak istiyorum.
innertext nedir innerHTML nedir?
innertext dışarıdan verilen girdiyi text olarak algılamasını sağlar.
Nasıl yani?
div.innerText = "<script>alert(1)</script>";
tam da böyle. Burdaki SCRİPT text olarak algılanır ve html içerisinde kod olarak okunmaz. Dolayısıyla XSS de olmaz.
InnerHTML ise tam tersi işler. Dışarıdan gelen veriri kod olarak işler ve XSS patlar.
f12'ye basıp elements,source kısımlarına geldiğinde innerhtml veya innertext'i arat ona göre sistemde XSS ara.

İnnertext ,textcontent ve innerHTML dikkat et
Payload yazıldıktan sonra arka planda neler oluyor az çok anlamış olmalıyız.
Neden her payload her sistemi tanıyamıyor. ?
Sistemi manipüle etmenin en temel ve kritik ucu seçtiğiniz payloadlardır.
(Payload nedir kısmına değinmeyeceğim çünkü bu yazıyı okuyorsan senin html,css,js, db,api,script ve xss nedir? kısımlarını bilmen gerekiyor.)
WAF'ı geçmenin en iyi tekniklerinden biri de seçilen payload'lardır. Seçtiğiniz payload ile WAF eğer manipüle edilirse sistemi kırılır ,güvenlik duvarı atlanır. Bundan dolayı sizin payloadı çok iyi seçmeniz gerekiyor.
NOT: Bu cümlelerden sadece payload seçmenin waf'ı atlamak olduğu çıkarımı doğru değil.
Payloadları neye göre seçiyoruz?
Unutma;
XSS, payload denemek değil ; verinin sistem içinde nasıl işlendiğini analiz etmektir.
Rastgele payload atalım search kısmına olmaz mı :)

olmaz hocam olmaz.
Hangi payload'ı neden seçtiğini bilmeliyiz.
Her bir payload'ın farklı bir hedefi ve farklı bir amacı vardır.
Sen siteden ne istiyorsun da XSS arıyorsun?
Her bir payload'ın enjekte edilmek istendiği sitenin iş akış mantığı farklıdır.
<script>alert(123)</script>
' alert(1);
<IMG SRC=jAVasCrIPt:alert('XSS')>
<form><isindex formaction="javascript:confirm(1)"
<div onmouseover='alert(1)'>DIV</div>
'alert(document.cookie);//
Buradaki her bir payload farklı çıktı verir ve hedefi farklıdır.
Adım adım ele aldığımız payloadları tanıyalım.
<script>alert(123)</script>
Burdaki hedef direkt HTML içerisinde js kodu çalıştırmaktır.
Burada test ettiğin şey sitenin raw basıp basmadığıdır.
' alert(1);
Burdaki amaç JS context'ten kaçmak
Script engeli olan bir sitede kullanılır.
<IMG SRC=jAVasCrIPt:alert('XSS')>
Burda amaç direkt waf bypass etmektir. Script engeli olan bir backendi+waf'ı atlatmak için kullanırız.
Normalde HTML içerisinde görseller img olarak kullanılır. Senin kullandığın bu payload'ı sistem img olarka algılayıp kod olarak çalıştırabilir ve XSS bamm
<form>< formaction="javascript:confirm(1)"
Bu payload eski sistemlerde kullanılır. FORM kullanmamızın sebebi, kullanıcı etkileşimiyle javascript: üzerinden kod çalıştırabilen bir mekanizma yaratmak
<div onmouseover='alert(1)'>DIV</div>
Burada mantık HTML içerisinde bir bölüm oluşturmak. Zaten HTML' de DİV mantığı da böyledir.
Syafada div bölümü oluşur mouse oluşan bu bölümün üzerine gelince alert tetiklenir.
'alert(document.cookie);//
Burada maksat sadece alert vermek değil document.cookie ile maksat sistemden veri çekmektir.
Burdaki hedef session verilerine özellikle de cookielere erişmektir.
Genel itibariyle kullanılan bazı payloadları böyle tek tek açıklamanın faydalı olacağını düşündüm. Her birinin hedefi ve kullanım amacı bizler için kırılma noktasını oluşturuyor.
Payloadları şu mantığa göre seç
Payload seçimi = context + hedef + filtre durumu
Rastgele payload sallamak neymiş gördün mü kral

Bir pentester sitede XSS ararken şu sorulara cevap bulabilmeli

Encoding var mı?
Encoding yoksa ve kullanıcı girdisi HTML veya JavaScript olarak gönderilirse , tarayıcı bu veriyi kod olarak yorumlayabilir.
Yanlış context'te mi uygulanmış?
İstek nereye gidiyor?
HTML Mİ
JS Mİ
Attirube mu?
Template escape kapalı mı?
Senin verin escapeden geçip text olarak mı algılanıyor yoksa escape kapalı mı?
JSON içinde HTML var mı?
f12'ye bas ve network source elements kısımlarını didikle
CSP zayıf mı?
Sistem hangi scriptleri kabul ediyor hangilerini kabul etmiyor mantığıyla çalışan bir güvenlik politikasıdır
backend browser'e CSP gönderir browser'de bunları uygular.
XSS'in sistem içerisinde işleyişi noktasında aktaracaklarım bu kadar.
Eksikleri ve hatalı kısımları yorumda belirt lütfen. Birbirimizden öğrenelim istiyorum.
Bir sonraki konularda görüşmek üzere..
ZEKİ KAYAALP