Skip to content

Manchmal verarbeiten Webseiten verschiedene Anfragen, ohne passende Sicherheitsmaßnahmen. Das kann dazu führen, dass Daten von mehreren Threads zur gleichen Zeit bearbeitet werden. Dadurch können kollisionen entstehen. ![[Pasted image 20240515172419 1.png]]

  • Mehrfaches senden ohne Anpassungen

    Bei einer einfachen Race Condition, also wo lediglich ein Request mehrfach verschickt werden muss kann race-single-packet-attack.py aus den Beispielen genutzt werden. Statt dem Turbo Intruder kann auch der Repeater genutzt werden. Dazu wird eine Gruppe erstellt mit dem Request. Dieser Request wird dann dupliziert und die Gruppe wird in parallel verschickt.
  • Ensure that the target supports HTTP/2. The single-packet attack is incompatible with HTTP/1.
  • Set the engine=Engine.BURP2 and concurrentConnections=1 configuration options for the request engine.
  • When queueing your requests, group them by assigning them to a named gate using the gate argument for the engine.queue() method.
  • To send all of the requests in a given group, open the respective gate with the engine.openGate() method.
  • Mehrfaches Senden unterschiedlicher Anfragen

    #TODO In race conditions "Single-endpoint race conditions" verstehe ich nicht richtig Das Senden von Parallelen Anfragen zu einem einzigen Endpunkt, kann auch Race Conditions auslösen.
  • Senden an mehrere Endpunkte

    Es kann auch sein, dass es nötig ist an verschiedene Endpunkte Anfragen zu machen, um die Race Condition auszunutzen. Beispielsweise im folgenden Bild ist zu sehen, wie ein Artikel gekauft wird. Nachdem der Bezahlvorgang ausgeführt wird, gibt es eine Validierung der Bezahlung und danach wird der Einkaufskorb validiert. Während der Validierung der Bezahlung existiert ein Zeitfenster um den Einkaufswagen zu ändern und zusätzliche Artikel hinzuzufügen. ![[Pasted image 20240517150010 1.png]]
  • Aufwärmen der Verbindungen

    Manchmal kann es vorkommen, dass es zu verzögerungen durch das Netzwerk kommt. Dafür können Requests vorrausgeschickt werden, damit diese Verzögerungen die Ergebnisse nicht beeinflussen. Manchmal verlangsamen Webserver die Verbindungen auch, wenn zu viele Verbindungen eintreffen, dies kann ausgenutzt werden für die Race Conditions.
  • Session basierte sperr Mechanismen

    Es kann sein, dass es einen Schutz gibt gegen race conditions durch das verhindern innerhalb sessions. Dies ist beispielsweise beim PHP nativen Session handler der Fall. Das Absenden dieser Requests von unterschiedlichen Sessions, kann dies umgehen.
  • Partial construction race conditions

    Manche Anwendungen kreirren Objekte in mehreren Schritten. Das kann dazu führen, dass es einen Mittelzustand gibt, indem das Objekt verwundbar ist. Dies kann beispielsweise passieren, wenn ein neuer Nutzer angelegt wird und im zweiten Schritt ein API Key erstellt wird. Dies kann dazu führen, dass es möglich ist in die Datenbank ein Eingabewert zu injizieren, welcher mit dem nicht initialisierten Wert übereinstimmt. Frameworks lassen oft arrays und nicht string datenstrukturen mit nicht standardsyntax zu. Beispielsweise PHP:
  • param[]=foo ist äquivalent zu param = ['foo']
  • param[]=foo&param[]=bar ist äquivalent zu param = ['foo', 'bar']
  • param[] ist äquivalent zu param = [] Bei Ruby on Rails ist es ähnlich. param[key] resultiert in dem folgenden Server seitigem Objekt: params = {"param"=>{"key"=>nil}}
  • Zeit sensitive Attacken

    Manchmal gibt es keine race conditions, aber präzises timing kann Schwachstellen enthüllen. Dies kann der Fall sein, wenn ein Security Token mit einem Timestamp erstellt wird. Daher kannn es nützlich sein Requests zur gleichen Zeit zu senden
  • Engines von Turbo Intruder

    Engine.HTTP2 Engine.THREADED Engine.BURP2 Engine.BURP
  • Feintunning

    Wortlisten sollten nicht vorgeladen werden, sondern gestreamt werden:
    for word in open('/usr/share/dict/words'):       
    engine.queue(target.req, word.rstrip())
    
  • Bereits gesehene Wörter als Wortliste

    # list of all words observed during passive scans
      for word in wordlists.observedWords:
          engine.queue(target.req, word)
    
  • Mehrere Parameter

    Parameter können im Request mit %s angegeben werden.
    for firstWord in open('/usr/share/dict/words'):
        for secondWord in open('/usr/share/dict/american-english'):
          engine.queue(target.req, [firstWord.rstrip(), secondWord.rstrip()])
    
  • Filtern von Antworten

    Die Antworten werden nicht automatisch gespeichert, sie müssen hinzugefügt werden.
    `def handleResponse(req, interesting):   
    if '200 OK' in req.response:   
    table.add(req)`
    
  • Antwort Decorators

    Die Decorator werden von oben nach unten abgearbeitet.
Zweck Beispiel
Anzeige der Response Codes @MatchStatus(200,204)
Response Codes nicht anzeigen @FilterStatus(200,204)
Zeigt Antworten mit der spezifizierten Größe @MatchSize(555)
Zeigt Antworten die nicht der Größe entsprechen @FilterSize(555)
Zeigt nur Antworten in der Reichweite der größe @MatchSizeRange(100,1000)
Zeigt Antworten außerhalb der größe @FilterSizeRange(100,1000)
Nur wenn bestimmter Regex auftritt @MatchRegex(r".*Set-Cookie.*")
Nur wenn Regex nicht vorkommt @FilterRegex(r".*Not Found.*")
Anzeige wenn Antwort Anzahl der Wörter enthält @MatchWordCount(3)
Anzeige wenn wort Anzahl nicht stimmt @FilterWordCount(3)
Anzahl der Wörter in Reichweite @MatchWordCountRange(3, 6)
Anzahl der Wörter nicht in Reichweite @FilterWordCountRange(3,6)
Anzahl der Zeilen @MatchLineCount(1, 2, 3)
@FilterLineCount(LineCount, ...) @FilterLineCount(LineCount, ...)
@MatchLineCountRange(min, max) @MatchLineCountRange(min, max)
@FilterLineCountRange(min, max) @FilterLineCountRange(min, max)
Zeigt nur n Antworten bestimmter Größe @UniqueSize(instances=n)
Zeigt nur n Antworten mit bestimmter Wort Anzahl @UniqueWordCount(instances=n)
Zeigt nur n Antworten mit gleicher Zeilenanzahl @UniqueLineCount(instances=n)
- ## Quellen
https://book.hacktricks.xyz/pentesting-web/race-condition