Tüm Koşullara tur bindirecek koşul – Race Condition’ı anlamak -Eşzamanlılık hataları – CWE 362

Race Condition Nedir?

Herkesin birbirini geçmek için daha fazla teknolojiye, kaynağa ve hıza ulaşmak istediği bu çağda hız tek başına bir anlam ifade etmiyor. Yoksa ediyor mu?

Bu yazıda race condition olarak bilinen yarış koşulu zafiyetlerini inceleyeceğiz. Tam teknik hitabı; işlemin gerçekleşme hızına bağlı olarak manipüle edilebilen koşul tabanlı zafiyetler olan bu açıklıklar aslında oldukça ilginç ve çok basit dokunuşlarla iş akışının bozulmasıyla güvenlik sürecinin tehlikeye düşürülmesini konu alıyor.

Farklı iş parçacıkları arasında uygun kilitleme mekanizmalarının ve senkronizasyonun olmaması nedeniyle, bir saldırgan sistemi kötüye kullanabilir ve birden fazla kez bir aksiyonu gerçekleştirip, yetkisinin ötesinde işlemler yapabilir.

Kayıt Ekleme Sınırı ile Race Condition Örneği

Bir uygulama hayal edelim. Bu uygulamada bir kayıt fonksiyonu var ve bu fonksyionda bir limit var. Kullanıcı, 5 kayıttan fazla ekleyemeyecek şekilde limitlenmiş. Yarış kondisyonu zafiyetinden faydalanarak 5 kayıttan fazla eklenmesi örneğini inceleyeceğiz.

Bu örnekteki yaklaşım aynı şekilde para transferleri veya hediye kodu kullanımı gibi popüler race condition örnekleri üzerinde de aynıdır.

Hız kondisyonlarını anlamak için önce istemci ve server arası ilişkiyi anlamamız gerekir.

Network latency: Ağ gecikmesidir. İstek, kullanıcı bilgisayarından servera ulaşana kadar yaşanan gecikmenin toplamıdır.

Jitter: Ağ gecikmesinin belirsizliğinden doğan değişkendir, aslında ağ gecikmesinin alt başlığıdır.

Internal latency: İşlemin serverda işlenme süresinin tamamıdır. Sonlandığında elde edilen çıktı yine ağ gecikmesinden etkilenerek kullanıcıya gönderilir.

İsteğin istemciden sunucuya iletilip işlenme süreci bölümünde gördüğümüz üzere, istemci ve sunucu cevabının dönmesi arasında; ağ gecikmesi, ağ gecikmesi belirsizliği (jitter), sunucunun işleme süresi (iç gecikme) gibi zaman parçaları yer almaktadır. Yarış kondisyonunun gerçekleşebileceği zaman aralığı ise iç gecikmenin içinde yer almaktadır. Bu zaman aralığını avantajımızıza kullanmayı ve bunu ağ gecikmesinden etkilenmeden gerçekleştirebilmek için burp vekilini nasıl kullanacağımızı yazının ilerleyen bölümlerinde işleyeceğiz.

İç gecikme ise kendi içinde, bir programın çalışma mantığına göre alt başlıklara ayrılır. Bu örnekte 5 adıma ayrılmıştır. Duruma göre daha fazla veya daha az adım içerebilir.

Burada başarısız bir hız kondisyonu denemesini inceleyeceğiz. Kayıt limitinin aşılmasına bir kayıt kaldığı bir durumda olduğumuzu farz edelim. Arka arkaya istekler göndererek belirlenene limit sayısından fazla kayıt oluşturmaya çalışacağız.

Bu durumda bir istek gönderirsek henüz limite ulaşılmadığı için başarı ile işlenir. Hız kondisyonu zaman aralığından faydalanması için özelleştirilmemiş, yani sıradan ikinci bir isteği gönderdiğimize limite takılacağı için başarı ile işlenmeyecektir. İç gecikmeyi oluşturan işlem zamanının içindeki, kayıt kontrolü yapan ve kayıt sayısının yükselten işlemler tamamlandıktan sonra işlenmeye başlayan ikinci istek başarı ile işlenmez. Çünkü kayıt kontrolü yapıldığında dönen cevap kayıt limitine ulaşıldığıdır.

Burada ise başarılı bir hız kondisyonu istismarını inceleyeceğiz. Görülen üzere isteklerin hedefi gerçekleştirebilmesi için henüz kayıt sayısının yükseltilme işlemi gerçekleşmeden önce diğer isteklerinde işlenmeye başlanmış olmasını gerektiriyor. Bu süreç milisaniyeler içinde gerçekleştiği için network jitterının minimize edilmesi gerekiyor. Bunu sağlayan Burp suite vekilinin özelliklerinin birazdan inceleyeceğiz.

Sürecin başarılı olması için iç gecikmeyi yaratan işlem sürecinin başlarında diğer isteklerinde servera ulaşması ve işlenmeye başlanması gerekiyor. Detaylıca inceleyelim; yine henüz 4 kayıdın oluşturulduğunu ve 5 kayıtın limit olduğunu varsayalım.

Giden ilk istek için kayıt kontrolü yapıldığında kayıt sayısı 4’tür. Bu yüzden istek işlenmeye devam eder. İkinci istek işlenmeye başlandığında, ilk isteğin işlenmesi henüz tamamlanmadığı için kayıt sayısı hala 4’tür. Bu durum 3. istek işlenmeye başladığında da geçerlidir. Bu zafiyetin var olması için gereken kısa zaman aralığından faydalanan bu isteklerin işlenmesi tamamlandığında ise kayıt sayısı 7’ye çıkmıştır. İstek işlenirken limite takılmamıştır çünkü, tüm isteklerin işlenmesi başladığında kayıt sayısı 4 idi.

Tüm bu örneklerden ve görsellerden de anlayacağınız üzere bu kısa zaman aralığında oldukça kısıtlı sayıda istek bu zafiyeti başarı ile sömürebilir. Milisaniyelik zaman aralığının dışında kalan istekler başarılı sonuç elde edemeyecektir.

Gelin şimdi burp suite’in hız kondisyonu için sunduğu özelliklere bakalım.

Burp Attack Group Nedir?


Burp suite’nin gruplama özelliği ile çeşitli saldırı türlerinden faydalanabilecceğiniz biliyor muydunuz? İstekleri repeater’a gönderdikten sonra gruplamak istediğiniz isteklerin herhangi birinin üstüne sağ tıklayıp add tab to group > create tab group seçeneklerini seçiyoruz. Sonrasında ise bu gruba dahil etmek istediğimiz istekleri ve istediğimiz rengi seçiyoruz ve hazır. Ek olarak artık send butonun yanında bir açılır menü oku görüyoruz. İşte şimdi bu oku kullanarak race condition için özel olarak eklenmiş bir özellikten faydalanacağız.

Single Packet Attack Nedir?


Tek paket saldırısı, birden fazla isteğin tek bir TCP paketiyle gönderilmesi yöntemidir. Bu saldırı, internet gecikmesinden (network jitter) kaynaklanan zaman farklarını ortadan kaldırır ve isteklerin neredeyse aynı anda hedefte işlenmesini sağlar. Bunu yapmak için istekler tek bir HTTP/2 bağlantısı üzerinden gönderilir, her isteğin küçük bir kısmı bekletilir ve ardından son parçaları aynı anda iletilir. İşletim sistemi bu parçaları tek bir TCP paketi hâline getirir, böylece tüm istekler hedefe neredeyse eş zamanlı ulaşır.

Single Packet Attack hakkında daha fazla bilgi almak için Port Swigger’ın yazısını okuyabilirsiniz.

Single Connection Attack

Tek bağlantı yöntemi saldırısında ise tüm istekler tek bir TCP bağlantısı üzerinden art arda gönderiliyor. Ama istekler sırayla işleniyor yani birbirine çok yakın zamanlarda işlenmeleri sağlanıyor ama tamamen aynı anda değil.

Amaç, istemci tarafında zamanlama farklarından kaynaklanan desync (uyumsuzluk) zafiyetlerini test etmek ve TCP bağlantısı kurarken oluşan küçük gecikmeleri azaltmak. Bu teknik race condition var mı yok mu gözlemlemek için kullanılabilir.

Peki başka yol yok mu?

Tabi ki değil, bir örnek olarak bu tryhackme odasının [https://tryhackme.com/room/racetrackbank] çözüm rehberlerinde genellikle bir python scripti üzerinden arka arkaya isteklerin gönderilmesi işleniyor. Başka bir örnek olarak bende bir keresinde intruder ile arka arkaya istekler gönderirken yanlışlıkla race condition keşfetmiştim. Gereken temel özellik arka arkaya hızlı bir şekilde istekler gönderebilmek.

Race Condition Zafiyeti Nasıl Önlenir?

Race condition, birden fazla işlem veya kodun aynı anda paylaşılan bir kaynağa erişmeye çalıştığı durumlarda ortaya çıkar. Bu durumu anlamak için öznellik ve atomiklik kavramları önemlidir. Öznellik, bir kod parçası paylaşılan kaynağa erişirken başka kod parçalarının aynı kaynağı değiştirmemesi gerektiğini ifade eder. Eğer başka bir kod kaynağa müdahale ederse öznellik ihlal edilmiş olur. Atomiklik ise kod parçasının tek bir bütün olarak çalışmasını ifade eder; yani başka bir işlem kodun ortasında aynı kaynağa erişip müdahale edemez. Eğer bir başka kod parçası paylaşılan kaynağa müdahale edebiliyorsa ve bu iki kuralı bozuyorsa, race condition oluşmuş demektir.

Sekansal Sıralı Çalışma


Sekansal sıralı çalışma, işlemlerin veya kod parçalarının belirli bir sıra ile ve birer birer yürütülmesini ifade eder. Yani bir işlem tamamlanmadan diğerine geçilmez, her adım sırayla ve düzenli bir şekilde işler.

Atomik Operasyon


Bir işlem veya kod parçasının bölünemez ve bütün olarak çalışması demektir. Bir işlem atomik olduğunda, ortasında başka bir işlem devreye girip müdahale edemez; ya tamamen gerçekleşir ya da hiç gerçekleşmemiş sayılır.

Daha Fazla Bilgi İçin Ek Kaynaklar

https://cwe.mitre.org/data/definitions/362.html

https://portswigger.net/research/the-single-packet-attack-making-remote-race-conditions-local

https://portswigger.net/research/smashing-the-state-machine#single-packet-attack

https://portswigger.net/burp/documentation/desktop/tools/repeater/send-group#sending-requests-in-sequence