# Trkački uslov
\ Koristite [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) da biste lako izgradili i **automatizovali radne tokove** koji se pokreću najnaprednijim alatima zajednice na svetu.\ Dobijte pristup danas: {% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)! Drugi načini podrške HackTricks-u: * Ako želite da vidite **oglašavanje vaše kompanije u HackTricks-u** ili **preuzmete HackTricks u PDF formatu** proverite [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! * Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com) * Otkrijte [**The PEASS Family**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family) * **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Podelite svoje hakovanje trikova slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
{% hint style="warning" %} Da biste duboko razumeli ovu tehniku, proverite originalni izveštaj na [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) {% endhint %} ## Unapređivanje napada trkačkog uslova Glavna prepreka u iskorišćavanju trkačkog uslova je osigurati da se više zahteva obrađuje istovremeno, sa **vrlo malom razlikom u vremenu obrade - idealno manje od 1ms**. Ovde možete pronaći neke tehnike za sinhronizaciju zahteva: #### Napad jednim paketom HTTP/2 protiv sinhronizacije poslednjeg bajta HTTP/1.1 - **HTTP/2**: Podržava slanje dva zahteva preko jedne TCP konekcije, smanjujući uticaj mrežnog kašnjenja. Međutim, zbog varijacija na serverskoj strani, dva zahteva možda nisu dovoljna za dosledno iskorišćavanje trkačkog uslova. - **HTTP/1.1 'Last-Byte Sync'**: Omogućava prethodno slanje većine delova 20-30 zahteva, zadržavajući mali fragment koji se zatim šalje zajedno, postižući istovremeni dolazak na server. **Priprema za sinhronizaciju poslednjeg bajta** uključuje: 1. Slanje zaglavlja i podataka tela bez poslednjeg bajta bez završetka toka. 2. Zaustavljanje na 100ms nakon početnog slanja. 3. Onemogućavanje TCP_NODELAY da bi se koristio Naglov algoritam za grupisanje konačnih okvira. 4. Pingovanje za zagrevanje veze. Naknadno slanje zadržanih okvira trebalo bi rezultirati njihovim dolaskom u jednom paketu, što se može proveriti putem Wireshark-a. Ova metoda se ne primenjuje na statičke datoteke koje obično nisu uključene u napade trkačkog uslova. ### Prilagođavanje serverske arhitekture Razumevanje arhitekture cilja je ključno. Serveri na prednjoj strani mogu usmeravati zahteve na različite načine, što utiče na vreme. Preemptivno zagrevanje serverske veze, putem nebitnih zahteva, može normalizovati vreme zahteva. #### Prevazilaženje zaključavanja na osnovu sesije Okviri kao što je PHP-ov rukovalac sesijama serijski obrađuju zahteve po sesiji, što potencijalno prikriva ranjivosti. Korišćenje različitih sesijskih tokena za svaki zahtev može zaobići ovaj problem. #### Prevazilaženje ograničenja brzine ili resursa Ako zagrevanje veze nije efikasno, namerno izazivanje kašnjenja ograničenja brzine ili resursa veb servera putem poplave lažnih zahteva može olakšati napad jednim paketom stvaranjem kašnjenja na serverskoj strani pogodnog za trkačke uslove. ## Primeri napada * **Tubo Intruder - napad jednim paketom HTTP2 (1 endpoint)**: Možete poslati zahtev na **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), možete promeniti vrednost koju želite da probate metodom "brute force" za **`%s`** kao u `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`, a zatim izabrati **`examples/race-single-packer-attack.py`** iz padajućeg menija:
Ako želite da **pošaljete različite vrednosti**, možete izmeniti kod sa ovim koji koristi listu reči sa clipboard-a: ```python passwords = wordlists.clipboard for password in passwords: engine.queue(target.req, password, gate='race1') ``` {% hint style="warning" %} Ako veb ne podržava HTTP2 (samo HTTP1.1), umesto `Engine.BURP2` koristite `Engine.THREADED` ili `Engine.BURP`. {% endhint %} * **Tubo Intruder - Napad jednim paketom HTTP2 (Više krajnjih tačaka)**: U slučaju da trebate poslati zahtev na jednu krajnju tačku, a zatim više zahteva na druge krajnje tačke kako biste pokrenuli RCE, možete promeniti skriptu `race-single-packet-attack.py` na nešto poput: ```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) ``` * Takođe je dostupno u **Repeater-u** putem nove opcije '**Paralelno slanje grupe**' u Burp Suite-u. * Za **prekoračenje ograničenja** jednostavno možete dodati **istu zahtev 50 puta** u grupu. * Za **zagrevanje konekcije**, možete **dodati** na **početak grupe** neke zahteve ka delu veb servera koji nije statičan. * Za **odlaganje** procesa **između** obrade **jednog zahteva i drugog** u 2 podstanja koraka, možete **dodati dodatne zahteve između** oba zahteva. * Za više krajnjih tačaka RC-a možete početi slanje **zahteva** koji **ide ka skrivenom stanju** i zatim **50 zahteva** odmah nakon toga koji **eksploatišu skriveno stanje**.
### Sirovi BF Prethodno istraživanje je koristilo ove payload-e koji su samo pokušavali da pošalju pakete što je brže moguće kako bi izazvali RC. * **Repeater:** Pogledajte primere iz prethodne sekcije. * **Intruder**: Pošaljite **zahtev** Intruder-u, postavite **broj niti** na **30** unutar menija **Opcije**, izaberite kao payload **Null payloads** i generišite **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 - asyncio** Python - asyncio je biblioteka koja omogućava asinhrono izvršavanje koda. To je korisno za rukovanje trkačkim uslovima u veb aplikacijama. Da biste iskoristili asyncio, morate koristiti `async` i `await` ključne reči. `async` se koristi za definisanje asinhronih funkcija, dok se `await` koristi za čekanje na završetak asinhronih operacija. Kada se koristi asyncio, možete koristiti `asyncio.Lock()` objekat za sinhronizaciju pristupa deljenim resursima. Ovaj objekat obezbeđuje da samo jedan proces može pristupiti resursu u isto vreme. Evo primera koda koji koristi asyncio za rukovanje trkačkim uslovima: ```python import asyncio async def access_resource(lock): await lock.acquire() try: # Ovde se vrši pristup deljenom resursu print("Pristupam deljenom resursu...") await asyncio.sleep(1) print("Završio sam pristup deljenom resursu.") finally: lock.release() async def main(): lock = asyncio.Lock() tasks = [] for _ in range(5): tasks.append(access_resource(lock)) await asyncio.gather(*tasks) asyncio.run(main()) ``` U ovom primeru, `access_resource()` funkcija koristi `lock.acquire()` da bi se osiguralo da samo jedan proces može pristupiti deljenom resursu u isto vreme. Nakon pristupa resursu, funkcija čeka 1 sekundu koristeći `asyncio.sleep()` i zatim oslobađa zaključavanje pomoću `lock.release()`. `main()` funkcija kreira `asyncio.Lock()` objekat i pokreće pet instanci `access_resource()` funkcije koristeći `asyncio.gather()`. Kada se ovaj kod izvrši, svaka instanca `access_resource()` funkcije će se izvršiti asinhrono, ali će biti sinhronizovane korišćenjem `asyncio.Lock()` objekta. Ovo osigurava da samo jedan proces može pristupiti deljenom resursu u isto vreme, sprečavajući trkačke uslove. ```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()) ``` ## **Metodologija RC-a** ### Prekoračenje ograničenja / TOCTOU Ovo je najosnovniji tip trke uslova gde se **ranjivosti** pojavljuju na mestima koja **ograničavaju broj puta kada možete izvršiti određenu radnju**. Na primer, korišćenje istog koda za popust nekoliko puta u veb prodavnici. Veoma jednostavan primer može se pronaći u [**ovom izveštaju**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) ili u [**ovom bagu**](https://hackerone.com/reports/759247)**.** Postoji mnogo varijacija ovakvih napada, uključujući: * Višestruko iskorišćavanje poklon kartice * Višestruko ocenjivanje proizvoda * Podizanje ili prenos gotovine preko iznosa na računu * Ponovno korišćenje jedinstvenog rešenja CAPTCHA * Zaobilaženje ograničenja brzine protiv brute-force napada ### **Skriveni podstanja** Iskorišćavanje složenih trka uslova često uključuje iskorišćavanje kratkih prilika za interakciju sa skrivenim ili **nenamernim podstanjima mašine**. Evo kako pristupiti ovome: 1. **Identifikujte potencijalna skrivena podstanja** - Počnite tako što ćete identifikovati krajnje tačke koje menjaju ili interaguju sa kritičnim podacima, kao što su korisnički profili ili procesi za resetovanje lozinke. Fokusirajte se na: - **Skladištenje**: Dajte prednost krajnjim tačkama koje manipulišu podacima na serveru u odnosu na one koje rukuju podacima na klijentskoj strani. - **Radnja**: Potražite operacije koje menjaju postojeće podatke, jer su one verovatnije da će stvoriti iskorišćive uslove u poređenju sa operacijama koje dodaju nove podatke. - **Ključevi**: Uspešni napadi obično uključuju operacije koje se ključe na isti identifikator, na primer korisničko ime ili token za resetovanje. 2. **Sprovedite početno ispitivanje** - Testirajte identifikovane krajnje tačke sa napadima trke uslova, posmatrajući bilo kakve odstupanja od očekivanih rezultata. Neočekivani odgovori ili promene u ponašanju aplikacije mogu ukazivati na ranjivost. 3. **Pokažite ranjivost** - Sužite napad na minimalan broj zahteva potrebnih za iskorišćavanje ranjivosti, često samo dva. Ovaj korak može zahtevati više pokušaja ili automatizaciju zbog preciznog vremenskog usklađivanja. ### Napadi osetljivi na vreme Preciznost u vremenskom slanju zahteva može otkriti ranjivosti, posebno kada se koriste predvidljive metode poput vremenskih oznaka za sigurnosne tokene. Na primer, generisanje tokena za resetovanje lozinke na osnovu vremenskih oznaka može omogućiti identične tokene za istovremene zahteve. **Da biste iskoristili:** - Koristite precizno vremensko slanje, poput napada sa jednim paketom, kako biste izvršili istovremene zahteve za resetovanje lozinke. Identični tokeni ukazuju na ranjivost. **Primer:** - Zatražite dva tokena za resetovanje lozinke istovremeno i uporedite ih. Podudarajući tokeni ukazuju na grešku u generisanju tokena. **Proverite ovaj [PortSwigger Lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) da biste isprobali ovo.** ## Studije slučaja skrivenih podstanja ### Plaćanje i dodavanje stavke Proverite ovaj [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) da biste videli kako **platiti** u prodavnici i **dodati dodatnu** stavku koju **nećete morati platiti**. ### Potvrda drugih e-pošta Ideja je **verifikovati adresu e-pošte i istovremeno je promeniti u drugu** kako biste saznali da li platforma verifikuje novu adresu. ### Promena e-pošte na 2 adrese zasnovana na kolačićima Prema [**ovom istraživanju**](https://portswigger.net/research/smashing-the-state-machine), Gitlab je bio ranjiv na preuzimanje na ovaj način jer bi mogao **poslati** **token za verifikaciju e-pošte jedne adrese na drugu adresu**. **Proverite ovaj [PortSwigger Lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) da biste isprobali ovo.** ### Skrivena stanja baze podataka / Zaobilaženje potvrde Ako se koriste **2 različita upisa** za **dodavanje** **informacija** u bazu podataka, postoji mali vremenski period kada je **samo prvi podatak upisan** u bazu podataka. Na primer, prilikom kreiranja korisnika, **korisničko ime** i **lozinka** mogu biti **upisani**, a zatim se upisuje token za potvrdu novo kreiranog naloga. To znači da je tokom kratkog vremena **token za potvrdu naloga prazan**. Stoga, **registrovanje naloga i slanje nekoliko zahteva sa praznim tokenom** (`token=` ili `token[]=` ili bilo koja druga varijacija) za odmah potvrđivanje naloga može omogućiti **potvrdu naloga** gde ne kontrolišete e-poštu. **Proverite ovaj [PortSwigger Lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) da biste isprobali ovo.** ### Zaobilaženje dvofaktorne autentifikacije Sledeći pseudo-kod je ranjiv na trku uslova jer u vrlo kratkom vremenskom periodu **dvofaktorna autentifikacija nije primenjena** dok se sesija kreira: ```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 ``` ### Večna postojanost OAuth2 Postoji nekoliko [**OAuth provajdera**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers). Ovi servisi će vam omogućiti da kreirate aplikaciju i autentifikujete korisnike koje je provajder registrovao. Da biste to uradili, **klijent** će morati da **dozvoli vašoj aplikaciji** pristup nekim od njihovih podataka unutar **OAuth provajdera**-a.\ Dakle, do sada samo uobičajena prijava putem google/linkedin/github... gde vam se prikazuje stranica sa porukom: "_Aplikacija \ želi da pristupi vašim informacijama, da li želite da to dozvolite?_" #### Trkačka situacija u `authorization_code` **Problem** se javlja kada ga **prihvatite** i automatski šalje **`authorization_code`** zlonamerno aplikaciji. Zatim, ova aplikacija zloupotrebljava trkačku situaciju u OAuth servis provajderu da generiše više od jednog AT/RT (_Authentication Token/Refresh Token_) iz **`authorization_code`** za vaš nalog. U osnovi, zloupotrebiće činjenicu da ste prihvatili aplikaciju da pristupi vašim podacima da bi **kreirala nekoliko naloga**. Zatim, ako **prestane da dozvoljava aplikaciji pristup vašim podacima, jedan par AT/RT će biti obrisan, ali ostali će i dalje biti validni**. #### Trkačka situacija u `Refresh Token` Kada ste **dobili validan RT**, možete pokušati da ga zloupotrebite da biste generisali nekoliko AT/RT-a i **čak ako korisnik otkaže dozvole** za zlonamernu aplikaciju da pristupi njegovim podacima, **nekoliko RT-ova će i dalje biti validno**. ## **RC u WebSockets** U [**WS\_RaceCondition\_PoC**](https://github.com/redrays-io/WS\_RaceCondition\_PoC) možete pronaći PoC u Javi za slanje websocket poruka **paralelno** kako biste zloupotrebili **trkačke situacije i u Web Sockets**-ima. ## Reference * [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)
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)! Drugi načini podrške HackTricks-u: * Ako želite da vidite **oglašavanje vaše kompanije u HackTricks-u** ili **preuzmete HackTricks u PDF formatu**, proverite [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! * Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com) * Otkrijte [**The PEASS Family**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family) * **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
\ Koristite [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) da biste lako izgradili i **automatizovali radne tokove** uz pomoć najnaprednijih alata zajednice.\ Dobijte pristup danas: {% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}