İçeriğe geç
Sedat Özdemir
Yazılar

encryption

Görünmez Duvarları Yıkmak: IDOR’un Sessiz Çığlığı ve Mantık Hatalarının Anatomisi

Selam dostum, bugün seninle biraz dertleşelim, biraz da ellerimizi kirletelim. Kahveni (veya o meşhur enerji içeceğini) aldıysan konuya direkt dalıyorum. Bak,...

Sedat Özdemir
· 5 dk okuma

Selam dostum, bugün seninle biraz dertleşelim, biraz da ellerimizi kirletelim. Kahveni (veya o meşhur enerji içeceğini) aldıysan konuya direkt dalıyorum.

Bak, Red Team dünyasında veya genel olarak siber güvenlikte hepimiz çok havalı görünmeye çalışırız; terminalde akan yeşil yazılar, karmaşık exploit'ler, kırılamaz denen şifreleme algoritmalarını bypass etmeler falan... Ama dürüst olalım, bazen en büyük facialar en "basit" görünen yerlerden çıkıyor.

Hazırsan sana bir itirafla başlayayım. Henüz sektörde çok yeniyim, ilk ciddi sızma testimdeyim. Bir e-ticaret platformunu inceliyorum. Heyecan tavan, sanki her an FBI kapıma dayanacakmış gibi bir vibe'dayım. Sitede "Sipariş Detaylarım" diye bir bölüm var. URL'e baktım: site.com/view_order?id=1025.

İçimdeki o "hacker" fısıldadı: "Sedat, o 1025'i 1024 yap bakalım ne olacak?"

Yaptım. Ve bam! Başka bir müşterinin adı, soyadı, açık adresi ve aldığı tüm ürünler karşımda. "Vay be," dedim, "buldum!" Durur muyum? Bir Python script'i yazdım, başladım tüm ID'leri çekmeye. Maksat "PoC" (Proof of Concept) olsun, bak kaç veri sızıyor diyeyim. Ama o an fark etmedim ki sistem her sorguda arkada bir PDF oluşturup mail atıyormuş veya garip bir loglama tetikliyormuş. Sunucu benim "basit" script'im yüzünden şişti, müşterinin canlı veritabanı yavaşladı ve admin paneli kilitlendi. Sabahına müşterinin CTO'sundan gelen o telefonla uyandığımda, "pardon" demenin ne kadar yetersiz kaldığını acı bir şekilde öğrendim. İşte o gün, IDOR'un ve mantık hatalarının sadece "parametre değiştirmek" olmadığını, uygulamanın ruhunu anlamak gerektiğini kavradım.

IDOR: Sadece Bir Sayıdan Daha Fazlası

Şimdi gel, bu IDOR (Insecure Direct Object Reference) dediğimiz naneye biraz daha yakından bakalım. Çoğu kişi "Abi ID'yi değiştiriyorsun işte, neyi bu kadar abartıyorsun?" diyor. Ama kazın ayağı öyle değil. Günümüzün modern mimarilerinde artık öyle id=1 gibi basit yapılar pek kalmadı (tabii hala yapan varsa onlara selam olsun, işimizi kolaylaştırıyorlar).

Artık karşımızda UUID'ler, hashlenmiş ID'ler veya karmaşık token'lar var. Ama mantık hatası baki kalıyor. Bir Red Teamer olarak benim için bir UUID'yi tahmin etmek zordur ama imkansız değildir. Eğer uygulama o UUID'yi bir yerden sızdırıyorsa (örneğin bir yorum satırında, profil fotoğrafının metadata'sında veya bir JavaScript dosyasının içinde), o karmaşık yapı sadece bir illüzyona dönüşür.

Mesela, bir API endpoint'ini düşün:

# Klasik bir IDOR denemesi
curl -X GET "https://api.hedefsite.com/v1/user/profile/5001" \
     -H "Authorization: Bearer <senin_tokenin>"

Eğer bu istek sana 5002 ID'li kullanıcının verisini getiriyorsa, geçmiş olsun. Ama ya API şöyleyse?

# Daha sinsi bir durum
curl -X PUT "https://api.hedefsite.com/v1/update-settings" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer <senin_tokenin>" \
     -d '{"user_id": "9999", "email": "[email protected]", "role": "admin"}'

Burada gördüğün şey aslında Mass Assignment ile birleşmiş bir mantık hatası. Sen kendi token'ınla istek atıyorsun (kimlik doğrulama tamam), ama gövdede (body) başka bir user_id gönderiyorsun ve uygulama "Bu adam zaten login olmuş, demek ki ne gönderirse doğrudur" deyip o ID'yi güncelliyor. İşte bu, o meşhur "anahtarı kapının üzerinde unutmak" durumudur.

Mantık Hatalarının Karanlık Dehlizleri

Red Team lead olarak ekibime hep şunu söylerim: "Yazılımcı gibi düşün, ama biraz kötü niyetli bir yazılımcı." Web güvenliğinde teknik açıklar (SQLi, XSS gibi) artık WAF'lar veya modern framework'ler tarafından büyük ölçüde engelleniyor. Ama Business Logic Vulnerabilities (İş Mantığı Hataları) için henüz bir WAF kuralı yazılmadı. Çünkü o kural senin iş akışına özgüdür.

Şu senaryoyu hayal et: Bir bankacılık uygulaması veya bir ödeme sistemi.

  1. A hesabı B hesabına 100 TL gönderiyor.
  2. Uygulama kontrol ediyor: A hesabında 100 TL var mı? Evet.
  3. A'dan 100 TL düş, B'ye 100 TL ekle.

Peki, ben eksi miktar gönderirsem ne olur?

// Request
{
  "from_account": "Hacker_Account_ID",
  "to_account": "Victim_Account_ID",
  "amount": -10000
}

Eğer geliştirici amount > 0 kontrolünü yapmadıysa; matematiksel olarak Hacker'dan -10.000 düşmek (yani 10.000 eklemek) ve Victim'dan 10.000 düşmek anlamına gelir. Kulağa komik geliyor değil mi? "Kim yapar bunu?" diyorsun. İnan bana, en büyük finans devlerinde bile bu tarz "negatif değer" veya "integer overflow" hatalarıyla karşılaşıyoruz.

Burp Suite ile Dans: Intercept'in Gücü

Bu hataları bulmak için en büyük dostumuz tabii ki Burp Suite. Ama sadece isteği yakalayıp "Forward" demek yetmez. O isteği Repeater'a atıp, her bir parametreyle "Oynaman" lazım.

Diyelim ki bir indirim kuponu tanımlanıyor: KUPON10 sana %10 indirim sağlıyor. Peki, aynı kuponu bir istekte 10 kere gönderirsen ne olur? Ya da iki farklı kuponu aynı anda (Parameter Pollution) göndermeyi denersen?

POST /api/checkout HTTP/1.1
Host: shop.target.com
...
{
  "cart_id": "123",
  "coupon": ["KUPON50", "KUPON50"]
}

Veya daha "geek" bir hareket yapalım. Uygulama indirim miktarını sunucu tarafında değil de istemci tarafında (client-side) hesaplayıp gönderiyorsa?

POST /api/finalize-payment HTTP/1.1
...
{
  "total_price": "1500",
  "currency": "TRY",
  "discounted_price": "1" 
}

Sen orada discounted_price değerini 1 yaptığında sunucu bunu sorgusuz sualsiz kabul ediyorsa, o gün o şirketin zarar bilançosuna bir çizgi de sen çekmiş olursun. (Tabii biz etik hacker'ız, bunu raporluyoruz, o ayrı).

Kodun İçindeki Canavarı Evcilleştirmek

Peki, biz bu hataları nasıl engelleyeceğiz? İş arkadaşım olarak sana tavsiyem; asla ama asla istemciden gelen veriye güvenme. "Kullanıcı zaten login oldu, bu ID onundur" demeyeceksin. Her istekte, o nesneye erişim yetkisi olup olmadığını veritabanı seviyesinde kontrol edeceksin.

Bak, şöyle bir Node.js örneği üzerinden gidelim:

Hatalı Yaklaşım:

app.get('/api/invoice/:id', async (req, res) => {
    // Sadece ID ile faturayı getiriyor, kullanıcı kontrolü yok!
    const invoice = await Invoice.findById(req.params.id);
    res.json(invoice);
});

Doğru Yaklaşım:

app.get('/api/invoice/:id', async (req, res) => {
    const invoice = await Invoice.findOne({
        _id: req.params.id,
        ownerId: req.user.id // İstek atan kişinin ID'si ile eşleşmeli!
    });
    
    if (!invoice) {
        return res.status(403).send('Hoppala! Buraya girmeye yetkin yok dostum.');
    }
    res.json(invoice);
});

Gördüğün gibi, aradaki tek fark bir ownerId kontrolü. Ama işte o bir satır kod, binlerce verinin internete saçılmasını engelliyor.

Red Team Gözüyle Son Bir Dokunuş

Biz Red Team tarafında sızma testi yaparken sadece "açık bulmaya" odaklanmayız. O açığın işleyişine, organizasyona olan etkisine bakarız. IDOR bulduğumda, sadece bir kullanıcının verisini çekmekle yetinmem. "Acaba bu açık üzerinden admin yetkisine yükselebilir miyim (Privilege Escalation)?" veya "Tüm veritabanını dökebilir miyim (Data Exfiltration)?" sorularını kovalarım.

Eğer bir gün seninle bir projede karşılaşırsak, muhtemelen seni en çok zorlayacağım yer burası olacak. Kodun çok temiz olabilir, kütüphanelerin güncel olabilir ama o mantık akışındaki bir saniyelik dalgınlığın, benim içeri sızmam için yeterli bir kapı aralar.

Bu işin sırrı merak etmekte. "Peki bu parametreyi silersem ne olur?", "Peki bu isteği iki kere çok hızlı gönderirsem (Race Condition) ne olur?" diye sormaktan asla çekinme. Siber güvenlik, kuralları olan bir oyun gibi görünse de aslında kuralların etrafından nasıl dolanılacağını bulma sanatıdır.

Bugünlük benden bu kadar. Kendi yaptığım o acemice hatayı sakın unutma: Bir şeyi otomatize etmeden önce, manuel olarak neyi bozabileceğini iyi tart. Bir sonraki sefere belki biraz daha derinlere, konteyner güvenliğine veya bulut tarafındaki o karmaşık yetkilendirme hatalarına dalarız.

Hadi şimdi git ve o kodları biraz kurcala. Ama dikkat et, sunucuları patlatma! :)

Keep hacking.

İlgili yazılar