Devran Atuğ tarafından yazılmıştır.
Bu açığın temel sebebi sistemin çoklu iş parçacığı kullanmasından meydana gelir. Belirli sıradaki görevi yerine getirmek için tasarlanan sistemlerin aynı anda 2 veya daha fazla işlemi aynı anda gerçekleştirmeyi çalışırken sistemin zorlanmasından “Race Condition” açığı meydana gelir. Aslında bir tür güvenlik önleminin atlatmayla geçekleşir. İlk gönderilen isteğin güvenlik önleminin alınmaya çalışılan süre içerisindeki tekrardan gönderilen istekle güvenlik önlemi atlatılır.
Yukarıdaki kod parçacığı çalıştırıldığı zaman çıktı olarak “Iteration 0: x = 1751498” gibi bir çıktı görürsünüz 2 işlemci parçacığı kullanıldığı için eğer 200000 görür iseniz o kısımda tam denetim gerçekleştirilmiş anlamına gelir. Fakat 1751498 gibi sayıları görürseniz 200000 az o sırada güvenlik önlemi sırasında atlatılmış anlamına gelir. Süre üzerinden test yapmak istiyorsanız koddaki “for _ in range(100000):” kod satırının range kısmını 0 ekleyin veya cıkartın.
Ve benzeri kısımlarda tek hesap ile takip, abone, beğeni veya beğenmeme fonksiyonları binlerce kez kullanabilir.
Bazı örnek POC videoları;
Öncelikle “Race Condition” var olabileceği kısımları tespit edin. Tespit ettiğiniz fonksiyonu test etmek için burp ile isteği tutun.
Sonrasında isteği art arta atmak için BurpSuite Intruder kullanın çekirdek gücünü ortalama 50 parçacık gücünde olması idealdir. İsteğin herhangi bir kısmını değiştirin. Örneğin istek kısmının alt kısmına “x=5” gibi değer atayın yada “User-agent” kısmına BurpSuite ile işaretleyin, payload kısmından payload çeşitini “numbers” yapın ve değer atayın. Bunun nedeni ise web sitelerinin cache kısmını atlatmak için kullanılır.
Python kod parçacığı olarak çözümü;
Python threading modülü “Race Condition” için Lock sınıfını sağlar. Semafor nesnesi iş parçacığı tarafından erişimini kontrol eder ve senkronizasyon sağlar. “release()” ise eğer işlemci sınırın altında veya üstüne çıkarsa işlem “ThreadError ” olarak gösterir ve işlemi “FALSE” olarak gösterilir.
acquire() yapılır ise parçacık değerinin üstüne veya altına iner ise o işlemi false saymayacak ve işleme almayacak. Fakat “acquire([True])” yapılır ise herhangi bir sorunda direk programı sonlandırır ve hata verecektir.
Race Condition gibi kodlar üzerinden anlaşılması daha kolay olan zafiyetler “code review” yapan kişiler tarafından tespit edilmesi gerekiyor. Code review yapan kişiler bu oluşan hataları aynı zamanda comment satırları arasında belirtmesi gerekiyor.
[TR] Race Condition Nedir? Nasıl yapılır? Nasıl Önlenir?
Bu açığın temel sebebi sistemin çoklu iş parçacığı kullanmasından meydana gelir. Belirli sıradaki görevi yerine getirmek için tasarlanan sistemlerin aynı anda 2 veya daha fazla işlemi aynı anda gerçekleştirmeyi çalışırken sistemin zorlanmasından “Race Condition” açığı meydana gelir. Aslında bir tür güvenlik önleminin atlatmayla geçekleşir. İlk gönderilen isteğin güvenlik önleminin alınmaya çalışılan süre içerisindeki tekrardan gönderilen istekle güvenlik önlemi atlatılır.
Örnek zafiyetli kod parçacığı:
import threading
x = 0
def increment():
“””
x değeri hem fonksiyonlarda hem fonksiyonların dışında kullanılması icin global değişken olarak ayarlanır
“””
global x
x += 1
def thread_task():
for _ in range(100000):
increment()
def main_task():
global x
x = 0
#İş parçacıklar oluşturuluyor
t1 = threading.Thread(target=thread_task)
t2 = threading.Thread(target=thread_task)
# Çoklu iş parçacık başlatılıyor
t1.start()
t2.start()
“””İş parçacıkların olaya dahil olduğu an diğer işlemler işlerini bitirene kadar beklerler”””
t1.join()
t2.join()
if __name__ == “__main__”:
for i in range(10):
main_task()
print(f”Iteration {i}: x = {x}”)
Yukarıdaki kod parçacığı çalıştırıldığı zaman çıktı olarak “Iteration 0: x = 1751498” gibi bir çıktı görürsünüz 2 işlemci parçacığı kullanıldığı için eğer 200000 görür iseniz o kısımda tam denetim gerçekleştirilmiş anlamına gelir. Fakat 1751498 gibi sayıları görürseniz 200000 az o sırada güvenlik önlemi sırasında atlatılmış anlamına gelir. Süre üzerinden test yapmak istiyorsanız koddaki “for _ in range(100000):” kod satırının range kısmını 0 ekleyin veya cıkartın.
Nerelerde “Race Condition” Çıkabilir?
- Beğenme yada Beğenmeme
- Abone olma
- Takip etme
- Banka para çekme veya yatırma
Ve benzeri kısımlarda tek hesap ile takip, abone, beğeni veya beğenmeme fonksiyonları binlerce kez kullanabilir.
Bazı örnek POC videoları;
Race Condition Nasıl Yapılır?
Öncelikle “Race Condition” var olabileceği kısımları tespit edin. Tespit ettiğiniz fonksiyonu test etmek için burp ile isteği tutun.
POST /youtubei/v1/like/like?key= HTTP/1.1
Host: www.youtube.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0
Accept: */*
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer:Content-Type: application/json
X-Goog-Visitor-Id: CgtISWdqcG1tcTN0NCiJ6JiDBg%3D%3D
X-Youtube-Client-Name: 1
X-Youtube-Client-Version: 2.20210331.06.00
Authorization:
X-Goog-AuthUser: 0
X-Origin: https://www.youtube.com
Origin: https://www.youtube.com
Content-Length: 1923
Connection: close
Sonrasında isteği art arta atmak için BurpSuite Intruder kullanın çekirdek gücünü ortalama 50 parçacık gücünde olması idealdir. İsteğin herhangi bir kısmını değiştirin. Örneğin istek kısmının alt kısmına “x=5” gibi değer atayın yada “User-agent” kısmına BurpSuite ile işaretleyin, payload kısmından payload çeşitini “numbers” yapın ve değer atayın. Bunun nedeni ise web sitelerinin cache kısmını atlatmak için kullanılır.
Race Condition Nasıl Önlenir?
Python kod parçacığı olarak çözümü;
import threading
x = 0
def increment():
“””
x değeri hem fonksiyonlarda hem fonksiyonların dışında kullanılması icin global değişken olarak ayarlanır
“””
global x
x += 1
def thread_task():
for _ in range(100000):
lock.acquire()
increment()
lock.release()
def main_task():
global x
x = 0
#İş parçacıklar oluşturuluyor
t1 = threading.Thread(target=thread_task)
t2 = threading.Thread(target=thread_task)
# Çoklu iş parçacık başlatılıyor
t1.start()
t2.start()
“””İş parçacıkların olaya dahil olduğu an diğer işlemler işlerini bitirene kadar beklerler”””
t1.join()
t2.join()
if __name__ == “__main__”:
for i in range(10):
main_task()
print(f”Iteration {i}: x = {x}”)
Python threading modülü “Race Condition” için Lock sınıfını sağlar. Semafor nesnesi iş parçacığı tarafından erişimini kontrol eder ve senkronizasyon sağlar. “release()” ise eğer işlemci sınırın altında veya üstüne çıkarsa işlem “ThreadError ” olarak gösterir ve işlemi “FALSE” olarak gösterilir.
acquire() yapılır ise parçacık değerinin üstüne veya altına iner ise o işlemi false saymayacak ve işleme almayacak. Fakat “acquire([True])” yapılır ise herhangi bir sorunda direk programı sonlandırır ve hata verecektir.
Race Condition gibi kodlar üzerinden anlaşılması daha kolay olan zafiyetler “code review” yapan kişiler tarafından tespit edilmesi gerekiyor. Code review yapan kişiler bu oluşan hataları aynı zamanda comment satırları arasında belirtmesi gerekiyor.
Moderatör tarafında düzenlendi: