Single-Packet Race Condition: Web Uygulamalarında Milisaniyenin Altında Exploitation | Tağmaç - root@Tagoletta:~#
Contents

Single-Packet Race Condition: Web Uygulamalarında Milisaniyenin Altında Exploitation

Wed May 27 2026 · 4 min read

Category: Security Research

# Attack-Chain# Race-Condition# Exploit

Giriş: Neden Klasik Race Condition Testleri Başarısız Olur?

Race condition (yarış koşulu) güvenlik açıkları, uygulamanın bir kaynağı kontrol ettiği an ile kullandığı an arasındaki zaman penceresini sömürür. Bu sınıf TOCTOU (Time-Of-Check-Time-Of-Use) olarak bilinir.

Teoride basit görünür: aynı isteği aynı anda birden fazla kez gönder, kontrol mekanizmasını atla. Pratikte ise ağ gecikmesi (jitter) bu saldırıyı neredeyse imkânsız kılar. İki HTTP isteği, farklı ağ koşulları nedeniyle birbirinden 10–50ms sapabilir. Çoğu açık yalnızca 2–20ms'lik bir pencerede mevcuttur.

2023 yılında James Kettle (PortSwigger), DEF CON 31'de sunduğu "Smashing the State Machine" araştırmasıyla bu sorunu temelden çözen bir teknik geliştirdi: Single-Packet Attack.

Sub-State: Açığın Yaşadığı Yer

Race condition'ların çalışabilmesi için uygulamanın kısa süreli bir "ara durum"a (sub-state) girmesi gerekir.

Bir hediye kartı (gift card) redemption akışını düşünelim:

1. Bakiyeyi kontrol et  →  balance >= 100 ?  ✓
2. [SUB-STATE — ~5ms]   →  henüz düşülmedi
3. Bakiyeyi düş         →  balance -= 100

Eğer ikinci bir istek, "1" ve "3" adımları arasına girebilirse — yani bakiye henüz düşülmemişken tekrar kontrol başarılı olursa — kart birden fazla kez kullanılır.

Bu pencere genellikle 2–20 milisaniye arasındadır.

Single-Packet Tekniği

Klasik yaklaşımda her HTTP isteği ayrı bir TCP bağlantısı üzerinden gönderilir. Ağ koşulları nedeniyle istekler farklı milisaniyede sunucuya ulaşır. Pencere kaçırılır.

Single-packet tekniğinin çözümü:

HTTP/2 multiplexing sayesinde birden fazla request, tek bir TCP paketine sığdırılabilir. Aynı frame içindeki tüm requestler sunucuya aynı anda ulaşır — aralarında sıfır gecikme.

Son-frame senkronizasyonu (Last-Frame Sync):

  1. N-1 adet isteği hazırla, gönderme
  2. Son isteği de hazırla
  3. Hepsini tek bir TCP frame'e yükle
  4. Gönder → tümü eş zamanlı işlenir

CVE-2024-58248: nopCommerce Gift Card Race Condition

nopCommerce, yaygın olarak kullanılan açık kaynaklı bir e-ticaret platformudur. Hediye kartı kullanım uç noktasındaki işlem dizisi atomik değildir.

Savunmasız kod akışı (sadeleştirilmiş):

// GiftCardService.cs
public async Task<bool> RedeemGiftCard(string code, decimal amount)
{
    var card = await _giftCardRepo.GetByCode(code);
    
    // STEP 1: Check balance
    if (card.RemainingAmount < amount)
        return false;
    
    // SUB-STATE EXISTS HERE (~3-8ms)
    // card.RemainingAmount NOT YET updated in DB
    
    // STEP 2: Deduct
    card.RemainingAmount -= amount;
    await _giftCardRepo.Update(card);
    return true;
}

Veritabanı kaydı güncellenmeden önce aynı anda birden fazla istek Step 1'i geçerse, tümü Step 2'yi çalıştırır. 100$ değerinde bir kart birden fazla kez kullanılabilir.

Burp Suite ile exploit:

1. Burp Suite → Repeater → Yeni bir sekme grubu oluştur
2. Hediye kartı redemption isteğini sekme grubuna 5 kez ekle
3. "Send group (parallel)" seçeneğini kullan
4. HTTP/2 etkin olduğundan emin ol
5. Gönder → Tüm yanıtlar 200 OK dönüyorsa başarılı

Limit Overrun: Diğer Saldırı Senaryoları

Race condition yalnızca gift card'larla sınırlı değildir:

1. Rate limit bypass:

POST /api/send-otp HTTP/2
# 5 istek/dakika limiti varsa, 5 isteği aynı anda gönder
# Tümü limit sayacı artmadan işlenebilir

2. Para birimi işlemleri:

Bakiye: $50
Aynı anda gönder: Transfer $40 × 3
Sub-state'de 3 × kontrol geçer: $50 >= $40 ✓
Sonuç: $120 transfer edilir, $50 bakiyeden

3. Tek kullanımlık token'lar:

Email doğrulama token'ını aynı anda 3 kez kullan
Token "used" olarak işaretlenmeden önce tümü geçer

Turbo Intruder ile Otomasyon

Daha fazla eş zamanlı istek için Burp'ün Turbo Intruder eklentisi kullanılabilir:

def queueRequests(target, wordlists):
    engine = RequestEngine(
        endpoint=target.endpoint,
        concurrentConnections=1,
        requestsPerConnection=30,   # 30 request, 1 connection
        pipeline=True
    )
    
    for i in range(30):
        engine.queue(target.req)
    
    engine.start(timeout=10)

def handleResponse(req, interesting):
    if req.status == 200:
        table.add(req)

Tespit

Race condition açıklarını tespit etmek için:

  • Atomik işlemler yerine birden fazla DB sorgusu yapan uç noktalar
  • Bakiye/kredi/puan değiştiren endpoint'ler
  • Tek kullanımlık kaynak (token, kupon, davet linki) kullanan işlemler
  • Response süresinde ani değişiklikler

Önlem

1. Veritabanı düzeyinde atomik işlemler:

BEGIN TRANSACTION;
SELECT balance FROM gift_cards WHERE code = ? FOR UPDATE;
-- Lock row — concurrent reads blocked
UPDATE gift_cards SET remaining = remaining - ? 
WHERE code = ? AND remaining >= ?;
COMMIT;

2. Mutex / distributed lock:

using (await _lockService.AcquireLock($"giftcard:{code}"))
{
    // Only one thread enters at a time
    await RedeemGiftCard(code, amount);
}

3. Idempotency key'ler:

Her redemption isteği, tek kullanımlık bir idempotency key taşımalı. Aynı key ile gelen ikinci istek otomatik reddedilmeli.

Sonuç

Single-packet tekniği, race condition saldırılarını teorik olmaktan çıkarıp pratik bir tehdit haline getirdi. Milisaniye altı pencereler artık güvenilir biçimde istismar edilebilir durumdadır.

CVE-2024-58248, bu tekniğin gerçek dünya e-ticaret platformlarında ciddi mali kayıplara yol açabileceğini kanıtladı. Herhangi bir "kontrol et → kullan" akışı, atomik olmayan veritabanı işlemleri içeriyorsa potansiyel bir race condition barındırır.


CVE: CVE-2024-58248
Platform: nopCommerce
Araştırmacı: James Kettle / PortSwigger Research
Konferans: DEF CON 31 (2023), Black Hat USA 2023

Sıkça Sorulan Sorular

Web uygulamalarında race condition nedir?

Eşzamanlı işlenen iki isteğin küçük bir zaman penceresinde birbirine karıştığı bir kusurdur — örneğin durum güncellenmeden önce bir hediye kartını veya bakiyeyi iki kez kullanmak. Bu bir time-of-check to time-of-use (TOCTOU) hatasıdır.

Single-packet attack nedir?

James Kettle'ın, 20–30 isteği tek bir TCP paketinde varacak şekilde göndererek ağ titremesini ortadan kaldıran ve onları milisaniye altı pencerelere hizalayarak race condition'ları güvenilir şekilde tetikleyen tekniğidir.

Burp Suite ile race condition nasıl sömürülür?

Burp Repeater'ın grup halinde paralel gönderme özelliği, single-packet tekniğini otomatik kullanır; yazı, nopCommerce'deki CVE-2024-58248'i bu yolla sömürmeyi adım adım anlatır.

Race condition nasıl önlenir?

Veritabanı seviyesinde kilitleme veya atomik işlemler kullanın, idempotency anahtarları uygulayın, kaynak başına mutex kullanın ve durum değişikliklerini check-then-act yerine atomik olacak şekilde tasarlayın.