
Heute werden wir über einen der modernen Sicherheitsmechanismen für Webanwendungen sprechen, nämlich die Web Application Firewall (WAF). Wir werden moderne WAFs und ihre Basis sowie Bypass-Techniken, ihre Verwendung und warum Sie sich niemals vollständig auf WAF verlassen sollten, besprechen. Wir sprechen aus der Perspektive der Pentester; Wir haben nie WAFs entwickelt und nur Daten aus offenen Quellen gesammelt. Daher können wir uns nur auf unsere eigenen Erfahrungen beziehen und sind uns möglicherweise einiger Besonderheiten von WAFs nicht bewusst.
Haftungsausschluss: Dies ist eine Übersetzung des Artikels aus dem Russischen ins Englische. Der Artikel wurde Ende 2017 veröffentlicht. Einige Informationen könnten veraltet sein.Inhalt
- Einführung
- Die moderne WAF
- WAF identifizieren
- WAF Bypass Cheatsheet
- WAF-Bypass in der Praxis
- Fazit
Wenn Sie wissen, warum WAFs verwendet werden und wie sie funktionieren, können Sie direkt zum Bypass-Abschnitt springen.Einführung
WAFs sind in letzter Zeit sehr beliebt geworden. Anbieter bieten verschiedene Lösungen in verschiedenen Preisklassen, Distributionskits und Optionen für unterschiedliche Kunden an, von kleinen bis zu großen Unternehmen. WAFs sind beliebt, weil sie eine komplexe Lösung zum Schutz von Webanwendungen darstellen, die ein ganzes Spektrum von Aufgaben abdeckt. Aus diesem Grund können sich Web-App-Entwickler in einigen Sicherheitsaspekten auf WAF verlassen. WAFs können jedoch keine vollständige Sicherheit gewähren.

Was sollte ein WAF also in der Lage sein, seine Umsetzung in einem Projekt zu rechtfertigen? Seine Hauptfunktion besteht darin, jede Anforderung zu erkennen und zu blockieren, die nach der Analyse der WAF Anomalien oder einen Angriffsvektor aufweist. Die Analyse darf die Interaktion zwischen legitimen Benutzern und der Web-App nicht behindern und gleichzeitig Angriffsversuche genau und rechtzeitig erkennen. Um solche Funktionen zu implementieren, verwenden WAF-Entwickler reguläre Ausdrücke, Tokenizer, Verhaltensanalysen, Reputationsanalysen und natürlich maschinelles Lernen. Oft werden alle diese Technologien zusammen verwendet. WAF kann auch andere Funktionen implementieren: DDoS-Schutz, Verbot der IPs des Angreifers, Überwachung verdächtiger IPs, Hinzufügen von Sicherheitsheadern (X-XSS-Schutz, X-Frame-Optionen usw.), Hinzufügen von Nur-http-Flags zum Cookie, Implementierung von der HSTS-Mechanismus und CSRF-Token. Einige WAFs verfügen außerdem über clientseitige JavaScript-Module für Websites.
Natürlich schaffen WAFs einige Hindernisse für Hacker und Pentester. WAF macht das Auffinden und Ausnutzen von Sicherheitslücken ressourcenintensiver (außer wenn der Angreifer effektive 0-Tage-Bypass-Methoden für eine bestimmte WAF kennt). Automatische Scanner sind bei der Analyse von WAF-geschützten Web-Apps praktisch unbrauchbar. WAF ist ein zuverlässiger Schutz gegen „Scriptkiddies“. Ein erfahrener Hacker oder Forscher ohne ausreichende Motivation würde wahrscheinlich keine Zeit damit verschwenden wollen, Wege zu finden, um dies zu umgehen. Es ist zu beachten, dass je komplexer die Web-App ist, desto größer die Angriffsfläche und desto einfacher ist es, eine Bypass-Methode zu finden.
Bei unseren jüngsten Audits haben wir häufig verschiedene WAFs gefunden. Wir werden später über einige von ihnen sprechen. Wir haben bereits zwei proprietäre WAFs in zwei Hauptszenarien getestet:
- Wir wissen, dass eine Web-App eine bestimmte Sicherheitslücke aufweist, und versuchen, die WAF zu umgehen, um sie auszunutzen.
- Wir kennen keine Schwachstellen, daher müssen wir trotz der WAF eine finden und diese dann unter Umgehung der WAF ausnutzen.
Aber zuerst schauen wir uns die grundlegenden Mechanismen hinter WAF genauer an und sehen, welche Probleme sie haben.
Die moderne WAF
Um verschiedene Wege zur Umgehung der WAF effektiv finden zu können, müssen wir zunächst moderne Mechanismen der Anforderungsklassifizierung herausfinden. Jede WAF ist spezifisch und einzigartig aufgebaut, es gibt jedoch einige allgemeine Analysemethoden. Schauen wir uns diese an.

Regeln, die auf regulären Ausdrücken basieren
Die Mehrheit der vorhandenen WAFs verwendet Regeln, die auf regulären Ausdrücken basieren. Der Entwickler untersucht eine Reihe bekannter Angriffe, um wichtige syntaktische Strukturen zu identifizieren, die auf einen Angriff hinweisen könnten. Basierend auf diesen Daten erstellt der Entwickler reguläre Ausdrücke, die solche syntaktischen Strukturen finden. Es klingt einfach, aber diese Methode hat bestimmte Nachteile. Erstens kann ein regulärer Ausdruck nur auf eine einzelne Anforderung oder sogar auf einen einzelnen Anforderungsparameter angewendet werden, was offensichtlich die Effizienz solcher Regeln verringert und einige blinde Flecken hinterlässt. Zweitens führen die Syntax regulärer Ausdrücke und die komplexe Logik von Textprotokollen, die das Ersetzen äquivalenter Strukturen und die Verwendung unterschiedlicher Symboldarstellungen ermöglicht, zu Fehlern beim Erstellen dieser Regeln.
Scorebuilding
Diejenigen, die wissen, wie Netzwerk-Firewalls und Antivirenprogramme funktionieren, sollten mit diesem Mechanismus vertraut sein. Es erkennt keine Angriffe, ergänzt jedoch andere Mechanismen und macht sie präziser und flexibler. Die Sache ist, dass eine „verdächtige“ Struktur in einer Anfrage keine ausreichende Bedingung für die Erkennung eines Angriffs ist und zu vielen Fehlalarmen führen kann. Dieses Problem wird durch die Implementierung eines Bewertungssystems gelöst. Jede Regel, die auf regulären Ausdrücken basiert, wird durch Informationen zu ihrer Kritikalität ergänzt. Nachdem alle ausgelösten Regeln identifiziert wurden, wird ihre Kritikalität zusammengefasst. Wenn die Gesamtkritikalität den Schwellenwert erreicht, wird der Angriff erkannt und die Anforderung blockiert. Trotz seiner Einfachheit erwies sich dieser Mechanismus als effizient und wird häufig für solche Aufgaben verwendet.
Tokenizer
Diese Erkennungsmethode wurde auf der Black Hat 2012 als C / C + -Bibliotheks-
Libinjektion vorgestellt , mit der SQL-Injektionen schnell und präzise identifiziert werden können. Derzeit gibt es viele Libinjection-Ports für verschiedene Programmiersprachen wie PHP, Lua, Python usw. Dieser Mechanismus sucht nach Signaturen, die als eine Reihe von Token dargestellt werden. Eine bestimmte Anzahl von Signaturen wird auf die schwarze Liste gesetzt und gilt als unerwünscht und böswillig. Mit anderen Worten, bevor eine Anforderung analysiert wird, wird sie in eine Reihe von Token übersetzt. Token werden in bestimmte Typen unterteilt, z. B. Variable, Zeichenfolge, regulärer Operator, Unbekannt, Zahl, Kommentar, gewerkschaftsähnlicher Operator, Funktion, Komma usw. Einer der Hauptnachteile der Methode besteht darin, dass es möglich ist, eine Struktur zu erstellen, die zur falschen Bildung von Token führen würde. Daher weicht die Anforderungssignatur von der erwarteten ab. Diese Strukturen werden normalerweise als Token Breaker bezeichnet, und wir werden sie später diskutieren
Verhaltensanalyse
Das Erkennen und Blockieren von Ausnutzungsversuchen in Anforderungen ist nicht die einzige Aufgabe für WAFs. Es ist auch wichtig, den Prozess der Schwachstellensuche zu identifizieren, und die WAF muss entsprechend reagieren. Es kann sich in Scanversuchen, Brute-Force-Verzeichnissen, Parameter-Fuzzing und anderen automatischen Methoden äußern. Erweiterte WAFs können Anforderungsketten erstellen, die für normales normales Verhalten typisch sind, und Versuche blockieren, ungewöhnliche Anforderungen zu senden. Diese Methode erkennt Angriffe nicht so sehr, als dass sie den Prozess der Schwachstellensuche behindert. Das Begrenzen der Anzahl von Anforderungen pro Minute würde einen normalen Benutzer nicht beeinträchtigen, wäre jedoch ein ernstes Hindernis für Scanner, die in mehreren Threads arbeiten.
Reputationsanalyse
Dies ist ein weiterer Mechanismus, der direkt von Firewalls und Antiviren geerbt wird. Heutzutage enthält fast jede WAF Listen mit Adressen von VPNs, Anonymisierern, Tor-Knoten und Botnetzen, um Anfragen von diesen zu blockieren. Fortgeschrittene WAFs können ihre Basen automatisch aktualisieren und sie basierend auf dem analysierten Verkehr durch zusätzliche Einträge ergänzen.
Maschinelles Lernen
Dies ist einer der fragwürdigsten Aspekte von WAF. Beachten wir, dass der Begriff „maschinelles Lernen“ ziemlich weit gefasst ist und viele Technologien und Methoden umfasst. Außerdem ist es nur eine der Klassen der KI. "Implementierung" von maschinellem Lernen oder "Verwendung von KI" sind sehr beliebte Marketingphrasen. Es ist nicht immer klar, welche Algorithmen genau verwendet werden, und manchmal sieht es nur nach Kauderwelsch aus. Diejenigen Anbieter, die maschinelles Lernen wirklich nutzen und es effektiv durchführen, sind nicht bereit, ihre Erfahrungen zu teilen. Das macht es einem Außenstehenden schwer, die Situation herauszufinden. Versuchen wir dennoch, anhand der verfügbaren Informationen einige Punkte hervorzuheben.
Erstens hängt maschinelles Lernen vollständig von den Daten ab, auf denen es trainiert wurde, was ein bestimmtes Problem darstellt. Ein Entwickler sollte über eine aktuelle und vollständige Basis von Angriffen verfügen, was schwer zu erreichen ist. Aus diesem Grund protokollieren viele Entwickler die Ergebnisse ihrer WAFs gründlich und arbeiten mit den Anbietern von IDS- und SIEM-Systemen zusammen, um Beispiele für reale Angriffe zu erhalten. Zweitens kann sich ein in einer abstrakten Web-App trainiertes Modell in einer echten Web-App als völlig unwirksam herausstellen. Für eine bessere Qualität wird empfohlen, in der Implementierungsphase zusätzlich ein Modell zu trainieren, das ressourcenintensiv und zeitaufwändig ist und dennoch nicht die besten Ergebnisse liefert.
WAF identifizieren
WAF-Entwickler verwenden verschiedene Methoden, um den Benutzer zu benachrichtigen, dass die Anforderung blockiert wurde. Auf diese Weise können wir die WAF identifizieren, indem wir die Antwort auf unsere Angriffsanforderung analysieren. Dies wird normalerweise als WAF-Fingerabdruck bezeichnet. Fingerabdrücke können hilfreich sein, wenn eine WAF aus irgendeinem Grund nicht aktualisiert wird (gilt hauptsächlich für Open Source-Projekte). Die Entwickler proprietärer WAFs kümmern sich um ihre Kunden und implementieren automatische Updates. Sobald wir die WAF identifiziert haben, die sich als aktualisiert herausstellte, können wir die Informationen darüber weiterhin verwenden, um etwas über ihre Logik zu lernen.
Hier ist eine Liste möglicher WAF-Fingerabdrücke:
- Zusätzliche Cookies
- Zusätzliche Header zu jeder Antwort oder Anfrage
- Antwortinhalt (bei blockierter Anfrage)
- Antwortcode (bei blockierter Anfrage)
- IP-Adresse (Cloud WAF)
- JS clientseitiges Modul (clientseitige WAF)
Lassen Sie es uns anhand einiger Beispiele veranschaulichen
PT AFAntwortcode für blockierte Anforderung: 403
Kann das Client-Modul waf.js in die Antwortseite einfügen
Hauptteil der Antwort:
<h1>Forbidden</h1> <pre>Request ID: 2017-07-31-13-59-56-72BCA33A11EC3784</pre>
Ein zusätzlicher Header, den waf.js hinzufügt:
X-RequestId: cbb8ff9a-4e91-48b4-8ce6-1beddc197a30
Nemesida wafAntwortcode für blockierte Anforderung: 403
Hauptteil der Antwort:
<p style="font-size: 16px; align: center;"> Suspicious activity detected. Access to the site is blocked. If you think that is's an erroneous blocking, please email us at <a href="mailto:nwaf@pentestit.ru">nwaf@pentestit.ru</a> and specify your IP-address. </p>
WallarmAntwortcode für blockierte Anforderung: 403
Zusätzlicher Header: Nginx-Wallarm
Citrix NetScaler AppFirewallZusätzlicher Cookie:
ns_af=31+LrS3EeEOBbxBV7AWDFIEhrn8A000; ns_af_.target.br_%2F_wat=QVNQU0VTU0lP TklEQVFRU0RDU0Nf?6IgJizHRbTRNuNoOpbBOiKRET2gA
Mod_Security ver. 2.9Antwortcode für blockierte Anforderung: 403
Antwortstelle:
<head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>You don't have permission to access /form.php on this server.<br /></p>
Mod_Security ver. <2,9Antwortcode für blockierte Anforderung: 406 oder 501
Im Antworttext finden Sie mod_security, Mod_Security oder NOYB
Lack FirewallFügt der Antwort die folgenden Header hinzu:
X-Varnish: 127936309 131303037. X-Varnish: 435491096 Via: 1.1 varnish-v4
WAF-Entwickler entscheiden selbst, welcher Antwortcode im Falle einer blockierten Anforderung zurückgegeben werden soll. Es gibt auch einige spezifische Codes. Beispielsweise gibt Web_Knight WAF den Code 999 zurück, und dotDefender gibt den Code 200 mit einem leeren Antworttext oder einer Fehlermeldung zurück. Außerdem können Entwickler eine benutzerdefinierte Antwortseite mit anderen Inhalten erstellen.
WAF entwickelt sich wie jede andere App und ändert sich. Deshalb ist es wichtig, ständig die Relevanz Ihrer Fingerabdrücke zu überprüfen.
WAF Bypass Spickzettel
Die allgemeine Idee hinter der Suche nach Möglichkeiten zur Umgehung von WAF besteht darin, die von uns benötigte Anforderung so zu transformieren, dass sie für die Web-App weiterhin gültig ist, jedoch nicht für die WAF oder harmlos erscheint. Es ist wichtig, dass ein WAF-Typ viele verschiedene Servertypen bedienen kann, einschließlich der „exotischen“ Server wie Unicorn, Tornado, Weblogic, Lighttpd usw. Jeder Server kann exklusive Fälle von HTTP-Anforderungsanalyse auf unterschiedliche Weise wahrnehmen, was auch von WAF berücksichtigt werden sollte. Somit kann ein Angreifer die Serverspezifikationen der HTTP-Anforderungsanalyse verwenden, um eine Möglichkeit zu finden, die WAF zu umgehen.

Es ist schwierig, alle möglichen Möglichkeiten zur Umgehung von WAF entweder nach WAF-Sicherheitsmechanismen oder nach Anwendungsbereichen zu klassifizieren. Dieselben Bypass-Wege können interagieren und gleichzeitig verschiedene Komponenten eines WAF beeinflussen. Die unten beschriebenen Techniken wurden aus offenen Quellen gesammelt oder während unserer eigenen Forschung entdeckt und haben sich als eine der effektivsten erwiesen.
Hinzufügen spezieller Symbole
Verschiedene spezielle Symbole können die Analyselogik einer WAF verletzen und gleichzeitig vom Server gültig interpretiert werden. Variationen dieser Symbole können unterschiedlich sein: Sie können in Urlencode (obwohl die meisten WAFs damit umgehen können) oder andere Codierungen umgewandelt werden. Es ist auch möglich, spezielle Symbole ohne Codierung im Rohformat in eine Anfrage einzufügen, was für eine WAF eine Überraschung sein kann. Beispielsweise kann
\ r \ n \ r \ n in dieser Präsentation als das Ende eines HTTP-Anforderungshauptteils angesehen werden, und ein Nullbyte kann die Analyselogik regulärer Ausdrücke und Datenparser insgesamt verletzen. Es können auch andere spezielle Symbole aus den ersten zwanzig Symbolen der ASCII-Tabelle von Nutzen sein.
Beispiele:
- 0x00 - Null-Byte;
- 0x0D - Wagenrücklauf;
- 0x0A - Zeilenvorschub;
- 0x0B - Vertikale Registerkarte;
- 0x09 - Registerkarte Horizontal;
- 0x0C - Neue Seite
Bei der Suche nach einem Bypass ist es hilfreich, spezielle Symbole an verschiedenen Stellen im Anforderungshauptteil und nicht nur in Parameterwerte einzufügen. Wenn eine Anforderung beispielsweise im JSON-Format vorliegt, können wir NULL-Byte sowohl in einen Parameter als auch zwischen Parametern sowohl am Anfang als auch am Ende von JSON einfügen. Gleiches gilt für andere Formate des Hauptteils einer POST-Anfrage. Im Allgemeinen empfehlen wir, Nachforschungen anzustellen und Spaß zu haben, nach Orten zu suchen, die von WAF überwacht und analysiert werden können, und dort verschiedene spezielle Symbole zu verwenden.
Zum Beispiel:
{"id":1337,"string0x00":"test' or sleep(9)#"} {"id":1337,"string":"test'/*0x00*/ or sleep(9)#"} {"id":1337,"string"0x0A0x0D:"test' or sleep(9)#"}
<a href="ja0x09vas0x0A0x0Dcript:alert(1)">clickme</a> <a 0x00 href="javascript:alert(1)">clickme</a> <svg/0x00/onload="alert(1)">
id=13371 UNION SELECT version(), user()
Aus Gründen der Übersichtlichkeit haben wir spezielle Symbole durch ihre hexadezimale Darstellung ersetzt.Leerzeichen ersetzen
In den meisten Syntaxen müssen Schlüsselwörter und Operatoren getrennt werden, die bevorzugten Leerzeichen werden jedoch nicht angegeben. Daher können Sie anstelle der üblichen
0x20 (
Leerzeichen )
0x0B (vertikale Registerkarte) oder
0x09 (horizontale Registerkarte) verwenden. Das Ersetzen von Räumen durch Trennstrukturen ohne eigene Bedeutung fällt in dieselbe Kategorie. In SQL ist es
/ ** / (mehrzeilige SQL-Kommentare),
# \ r \ n (einzeiliger SQL-Kommentar, endend mit Zeilenvorschub),
- \ r \ n (alternativer einzeiliger SQL-Kommentar, endend) mit Zeilenvorschub). Hier einige Beispiele:
http://test.com/test?id=1%09union/**/select/**/1,2,3 http://test.com/test?id=1%09union%23%0A%0Dselect%2D%2D%0A%0D1,2,3
Außerdem können wir einen Ausdruck mithilfe der Syntax der Sprache transformieren, um Leerzeichen zu entfernen. In SQL können wir beispielsweise Klammern verwenden:
UNION(SELECT(1),2,3,4,5,(6)FROM(Users)WHERE(login='admin'))
Und in JS verwenden Sie
/ :
<svg/onload=confirm(1)>
Codierung ändern
Diese Methode basiert auf der Verwendung unterschiedlicher Codierungen, um zu verhindern, dass WAF an bestimmten Stellen Daten decodiert. Wenn beispielsweise ein Symbol durch seinen URL-Code ersetzt wird, kann WAF nicht verstehen, dass es Daten dekodieren muss, und leitet die Anforderung weiter. Gleichzeitig wird derselbe Parameter von der Webanwendung akzeptiert und erfolgreich dekodiert.
Die Dezimalform eines HTML-Symbols lautet
& # 106 oder
& # 0000106. WAF kennt möglicherweise die Kurzversion und kennt die Version mit zusätzlichen Nullen nicht (insgesamt sollten nicht mehr als 7 Symbole vorhanden sein). Ebenso lautet die Hex-Form eines HTML-Symbols
& # x6A oder
& # x000006A .
Es gibt auch einen Trick beim Entkommen von Zeichen mit einem Backslash
\ , zum Beispiel:
<svg/on\load=a\lert(1)>
Dies hängt jedoch davon ab, wie eine Web-App solche Eingabedaten verarbeitet. Die Sequenz
\ l wird also als
l verarbeitet und in ein einzelnes Symbol umgewandelt. WAF kann jedes Symbol separat verarbeiten und reguläre Ausdrücke oder eine andere WAF-Logik unterbrechen. Daher wird WAF die Schlüsselwörter übersehen. Mit dieser Technik können wir den Zeichen
\ n ,
\ r ,
\ t nicht entkommen, da sie in verschiedene Zeichen umgewandelt werden: neue Zeile, Wagenrücklauf und Tabulator.
HTML-Codierung kann in Tag-Attributen verwendet werden, zum Beispiel:
<a href="javascript:alert(1)">clickme</a> <input/onmouseover="javascript:confirm(1rpar;">
Diese Zeichen können leicht durch andere HTML-Darstellungen von Zielzeichen ersetzt werden. Hier können Sie verschiedene Transformationen von Charakteren nachschlagen.
Neben der HTML-Codierung können wir Zeichen mit
\ u einfügen:
<a href="javascript:\u0061lert(1)">Clickme</a> <svg onload=confir\u006d(1)>
Schauen wir uns auch den Vektor an, der sich auf das Einfügen von Sonderzeichen bezieht. Lassen Sie uns die Nutzdaten mit HTML-Codierung unterbrechen:
<a href="ja	vas
cript:alert(1)">clickme</a>
In diesem Fall können wir auch andere Trennzeichen einfügen.
Wir empfehlen daher, verschiedene Codierungen mit anderen Methoden zu kombinieren, um beispielsweise Sonderzeichen zu codieren.
Suche nach atypischen äquivalenten syntaktischen Strukturen
Diese Methode zielt darauf ab, einen Ausnutzungsweg zu finden, der von den WAF-Entwicklern nicht berücksichtigt wird, oder einen Vektor, der in der Stichprobe des maschinellen Lernens nicht vorhanden war. Einfache Beispiele wären JavaScript-Funktionen:
this, top self, parent, frame; Tag-Attribute:
Datenbindung, Ontoggle, Onfilterchange, Onbeforescriptexecute, Onpointerover, Srcdoc; und SQL-Operatoren:
lpad, field, bit_count .
Hier einige Beispiele:
<script>window['alert'](0)</script> <script>parent['alert'](1)</script> <script>self['alert'](2)</script>
SELECT if(LPAD(' ',4,version())='5.7',sleep(5),null);
Sie können auch die nicht symbolische Darstellung von JavaScript-Ausdrücken verwenden:
Ein offensichtliches Problem dabei sind lange Nutzlasten.
Der WAF-Bypass mit dieser Technik hängt vom Angriff und dem ausgenutzten Stapel von Technologien ab. Der berühmte ImageTragick-Exploit ist ein gutes Beispiel dafür. Die meisten WAFs, die vor diesem Angriff schützen, hatten Schlüsselwörter wie
URL ,
Kapazität und
Bezeichnung auf die schwarze Liste gesetzt, da diese Wörter in den meisten Veröffentlichungen und PoCs erwähnt wurden, die diese Sicherheitsanfälligkeit beschreiben. Es stellte sich jedoch bald heraus, dass auch andere Schlüsselwörter verwendet werden können, z. B.
kurzlebig und
pango . Infolgedessen könnten WAFs mit der Verwendung dieser Schlüsselwörter umgangen werden.
HTTP-Parameterverschmutzung (HPP) und HTTP-Parameterfragmentierung (HPF)
Der HPP-Angriff basiert darauf, wie ein Server gleichnamige Parameter interpretiert. Hier sind einige mögliche Umgehungen:
- Der Server verwendet den zuletzt empfangenen Parameter und WAF überprüft nur den ersten.
- Der Server vereint den Wert aus ähnlichen Parametern und WAF überprüft sie separat.
In der folgenden Tabelle können Sie vergleichen, wie verschiedene Server dieselben Parameter verarbeiten:

Der HPF-Angriff basiert wiederum auf einem anderen Prinzip. Wenn die Logik einer Webanwendung zwei und mehr Parameter in einer Anforderung vereint, kann der Gegner die Anforderung teilen, um bestimmte WAF-Prüfungen zu umgehen.
Die folgende SQL-Injection ist ein Beispiel für einen solchen Angriff:
http://test.com/url?a=1+select&b=1+from&c=base
HPF und HPP sind sich sehr ähnlich, aber die erste zielt auf eine Web-App ab, die zweite auf die Umgebung, in der sie betrieben wird. Die Kombination dieser Techniken erhöht die Wahrscheinlichkeit, eine WAF zu umgehen.
Unicode-Normalisierung
Die Unicode-Normalisierung ist eine Funktion von Unicode zum Vergleichen von Unicode-Symbolen, die gleich aussehen. Zum Beispiel haben die Symbole
'ª' und
'ᵃ' unterschiedliche Codes, sind aber ansonsten sehr ähnlich. Nach der Normalisierung sehen beide wie ein einfaches
'a' aus und werden als gleich angesehen. Durch die Normalisierung können einige komplexe Unicode-Symbole in ihre einfacheren Alternativen umgewandelt werden. Es gibt eine
Unicode-Normalisierungstabelle mit allen Unicode-Symbolen und ihren möglichen Normalisierungen. Mit ihm können Sie verschiedene Nutzdaten erstellen und mit anderen Methoden kombinieren. Es funktioniert jedoch nicht für alle Webanwendungen und ist sehr abhängig von der Umgebung.
In der obigen Tabelle sehen wir beispielsweise, dass sich die Symbole
<
und
﹤
in einfache
<
verwandeln. Wenn eine App nach der Normalisierung eine HTML-Codierung verwendet, wird höchstwahrscheinlich das normalisierte Symbol
<
in
<
. In anderen Fällen haben Entwickler diese Funktion möglicherweise übersehen und Unicode-Symbole nicht codiert. Auf diese Weise erhalten wir nicht HTML-codierte Symbole
< und
> , die in XSS-Angriffe umgewandelt werden können. WAF kann Probleme beim Verstehen von Unicode-Symbolen haben - es gibt möglicherweise einfach keine Regeln für solche Tricks, und das maschinelle Lernen kann auch nutzlos sein. Während wir in Webanwendungen mit Unicode-Normalisierung einen Bypass finden, können wir nicht nur
<>, sondern auch andere Symbole aus der Nutzlast ersetzen.
Zum Beispiel:
<img src﹦x onerror=alert︵1)>
Dieses Problem wurde kürzlich beim Rockstar BugBounty-Programm bei HackerOne festgestellt. Es gab keine WAF, nur strenge Benutzereingabefilterung:
hackerone.com/reports/231444hackerone.com/reports/231389Token Breaker
Angriffe auf Tokenizer versuchen, die Logik der Aufteilung einer Anfrage in Token mit Hilfe der sogenannten Token Breaker zu brechen. Token Breaker sind Symbole, mit denen die Korrespondenz zwischen einem Element einer Zeichenfolge und einem bestimmten Token beeinflusst und somit die Suche nach Signatur umgangen werden kann. Bei Verwendung von Token Breaker muss die Anforderung jedoch gültig bleiben. Die folgende Anforderung ist ein Beispiel für einen Angriff mit einem Token Breaker
SELECT-@1,version()
Dabei ist
- @ der Token Breaker.
Es gibt ein
Chear Sheet , das durch MySQL-Fuzzing und Überprüfung der Ergebnisse bei der Libinjektion erworben wurde.
Weitere Informationen zum Auffinden von Problemen bei der Libinjektion:
Noch ein FuzzerFuzz zu umgehenSo umgehen Sie die LibinjektionVerwenden der Funktionen von RFC
In den Spezifikationen für das HTTP / 1.1-Protokoll und verschiedenen Anforderungstypen (z. B. mehrteilige / Formulardaten) finden wir einige merkwürdige Dinge, die mit den Grenzfällen und Tricks der Verarbeitung von Headern und Parametern zusammenhängen. WAF-Entwickler berücksichtigen solche Probleme häufig nicht. Daher kann eine WAF eine Anforderung falsch analysieren und den Teil der Daten übersehen, in dem ein Angriffsvektor verborgen ist. Die meisten Probleme in WAFs hängen mit der Verarbeitung von mehrteiligen / Formulardaten und bestimmten Werten des Grenzparameters zusammen, der Parametergrenzen in solchen Anforderungen angibt. Außerdem können sich Serverentwickler ebenfalls irren und die Spezifikationen nicht vollständig unterstützen, sodass der HTTP-Parser eines Servers möglicherweise nicht dokumentierte Funktionen enthält.
Bei einer HTTP-Anforderung mit mehrteiligen / Formulardaten ist die Parametergrenze für die Trennung verschiedener Parameter im Hauptteil einer Anforderung zuständig. Laut RFC muss vor jedem neuen POST-Parameter eine zuvor festgelegte Grenze mit einem Präfix mit "-" gesetzt werden, damit der Server die verschiedenen Parameter einer Anforderung unterscheiden kann.
POST /vuln.php HTTP/1.1 Host: test.com Connection: close Content-Type: multipart/form-data; boundary=1049989664 Content-Length: 192 --1049989664 Content-Disposition: form-data; name="id" 287356 --1049989664--
Der Angriff kann auch auf der Tatsache beruhen, dass ein Server und eine WAF eine Situation, in der die Grenze leer bleibt, unterschiedlich behandeln. Laut RFC ist in diesem Fall „-“ die Grenze zwischen den Parametern. Trotzdem kann eine WAF einen Parser verwenden, der dies nicht berücksichtigt. Infolgedessen übergibt die WAF die Anforderung, da die Daten aus den Parametern einer POST-Anforderung nicht im Analysator angezeigt werden. Der Webserver kann eine solche Anfrage problemlos analysieren und die Daten zur weiteren Verarbeitung übergeben.
Hier sind einige weitere interessante Beispiele.
POST /vuln.php HTTP/1.1 Host: test.com Connection: close Content-Type: multipart/form-data; boundary= Content-Length: 192 -- Content-Disposition: form-data; name="id" 123' or sleep(20)# ----
Wir werden auf der ZeroNights 2016 einige weitere interessante Beispiele aus
Folien von
Bo0oM geben und erklären:
POST /vuln.php HTTP/1.1 Host: test.com Content-Type: multipart/form-data; boundary=FIRST; Content-Type: multipart/form-data; boundary=SECOND; Content-Type: multipart/form-data; boundary=THIRD; --THIRD Content-Disposition: form-data; name=param UNION SELECT version() --THIRD--
Bei diesem Angriff versuchen wir zu definieren, welcher der Grenzparameter von der WAF und welcher vom Webserver akzeptiert wird. Wenn sie unterschiedliche Parameter akzeptieren, ist es daher möglich, einen Angriff durchzuführen, indem eine Grenze angegeben wird, die die WAF nicht sieht. Dieser Angriff ähnelt HPP.
POST /vuln.php HTTP/1.1 Host: test.com Content-Type: multipart/form-data; xxxboundaryxxx=FIRST; boundary=SECOND; --FIRST Content-Disposition: form-data; name=param UNION SELECT version() --FIRST--
Dieser Angriff basiert auf der Annahme, dass es einen Unterschied beim Parsen einer HTTP-Anforderung durch die WAF und den Webserver gibt. Der Parser des Webservers sucht nämlich nach dem ersten 'Grenz'-Eintrag und dann nach dem' = 'Symbol und definiert erst danach den Wert der Grenze. Der WAF-Parser sucht seinerseits nur nach dem Eintrag "border =" und definiert dann die Grenze. Wenn diese Bedingungen erfüllt sind, findet die WAF die Grenze in der Anforderung nicht und kann daher den Parameter nicht finden und analysieren. Im Gegenteil, der Webserver erhält die Anfrage und verarbeitet den Parameter. Dieser Angriff funktioniert auch umgekehrt: Der Webserver-Parser sucht nach "border =" und der WAF-Parser sucht nur nach "border". In diesem Fall müssen wir nur die reale Grenze von FIRST auf SECOND ändern.
POST /somepage.php HTTP/1.1 Host: test.com Content-Type: multipart/form-data; boundary=Test0x00othertext; --Test Content-Disposition: form-data; name=param Attack --Test--
Dieser Angriff verwendet auch Sonderzeichen. Im Grenzparameter haben wir NULL-Byte hinzugefügt, damit der Webserver es abschneidet, aber die WAF es vollständig akzeptiert. In diesem Fall kann WAF den Parameter nicht analysieren, da er seine Grenzen nicht finden kann.
Maschinelles Lernen umgehen
Die Logik ist einfach: Wir müssen einen Angriff erstellen, der die Parameter des trainierten statistischen Modells erfüllt. Dies hängt jedoch stark davon ab, wie die WAF trainiert wurde und welches Trainingsmodell verwendet wurde. Manchmal ist es möglich, eine Lücke zu finden, manchmal nicht. Normalerweise benötigt eine WAF mit maschinellem Lernen in der Phase der Implementierung zusätzliche Schulungen, die auf der Anforderung an die Webanwendung des Kunden basieren. Dies stellt Pentester vor ein Problem: Parameter, die sich ähneln und sich von Anforderung zu Anforderung nicht wesentlich ändern, können nicht getestet werden, da ein Exkurs von der üblichen Parameterform als Anomalie angesehen wird.
Angenommen , Sie haben eine Anfrage an
api.test.com/getuser?id=123 . Die Parameter-ID ist immer numerisch und war im Trainingsbeispiel numerisch. Wenn das Modul für maschinelles Lernen in diesem Parameter etwas anderes als Zahlen findet, entscheidet es höchstwahrscheinlich, dass es sich um eine Anomalie handelt. Ein weiteres Beispiel: Angenommen, WAF wurde darauf trainiert, POST-Anforderungen an
api.test.com/setMarkDown mit POST-Parametern mit Markdown-Text zu klassifizieren. Offensichtlich kann es Anführungszeichen, spezielle Symbole und im Grunde alles im Markdown geben. In diesem Fall ist es viel einfacher, das Modul für maschinelles Lernen zu umgehen, da die WAF Anführungszeichen und spezielle Symbole toleriert.
Darüber hinaus zeigen wir anhand der Beispiele aus unserer Praxis, dass es aufgrund der Probleme beim Parsen von Parametern, die durch die oben beschriebenen Bypass-Methoden verursacht werden, nicht immer bis zum maschinellen Lernmodul reicht.
Im Allgemeinen müssen wir die Besonderheiten einer getesteten Anforderung und ihre Parameter berücksichtigen, mögliche Optionen für Parameterwerte voraussetzen, für die WAF möglicherweise tolerant ist, und darauf aufbauen.
Wann ist WAF nutzlos?
WAF analysiert Anforderungen und sucht in ihnen nach anomalem Verhalten. Es gibt jedoch einige Klassen von Schwachstellen, die nicht erkannt werden können. Zum Beispiel logische Schwachstellen, die keine Anomalien aufweisen, aber einige Aktionen aufweisen, die die Logik einer Webanwendung stören. Höchstwahrscheinlich wäre WAF auch im Falle von Race Condition, IDOR und unsicherer Benutzerauthentifizierung nutzlos.
Bestehende Dienstprogramme
Es gibt einige automatische Tools zum Auffinden von WAF-Bypässen, die von Enthusiasten auf diesem Gebiet geschrieben wurden. Hier sind die bekanntesten und würdigsten:
Glühbirnen-Framework - ein ganzes Framework zum Testen von mit WAF geschützten Web-Apps. Es ist auf Python geschrieben und zusätzlich als Plugin für Burp Suite portiert. Die Hauptmerkmale sind diese beiden Algorithmen:
- GOFA - ein aktiver Algorithmus für maschinelles Lernen, mit dem die Filterung und Desinfektion von Parametern in einer Web-App analysiert werden kann.
- SFADiff - deferentieller Black-Box-Testalgorithmus, basierend auf dem Training mit symbolischen endlichen Automaten (SFA). Es ermöglicht das Auffinden von Unterschieden im Verhalten von Web-Apps, wodurch WAF identifiziert und ein Bypass gefunden werden kann.
Bypass WAF - ein Plugin für Burp Suite, mit dem das automatische Ändern der Elemente im Hauptteil einer Anforderung nach verschiedenen Regeln und Codierungsänderungen eingerichtet werden kann. Es kann auch einen HPP-Angriff automatisieren.
WAFW00F - ein auf Python geschriebenes Tool zur WAF-Identifizierung. Es hat eine anständige WAF-Basis und wird noch aktualisiert. Die Ergebnisse können jedoch ungenau sein, da viele WAFs häufiger aktualisiert werden als das Projekt selbst.
Waf in der Praxis umgehen

Wir haben einen Penetrationstest eines Online-Shops durchgeführt, der durch
PT AF (Positive Technologies Application Firewall) geschützt war. Es war schwer, eine Schwachstelle zu finden, die eine Basis für eine Umgehung sein könnte. Aber bald haben wir ungewöhnliches Verhalten auf der Seite der Web-App entdeckt, das nicht von der WAF gefiltert wurde. Die Anomalie wurde bei der Suche in der Geschichte der gekauften Waren gefunden. Die Anfrage wurde im JSON-Format gesendet und sah folgendermaßen aus:
{"request":{"Count":10,"Offset":0,"ItemName":"Phone"}}
Wir haben die Werte
Phone ' und
Phone' + ' in den Parameter
ItemName eingefügt und festgestellt, dass der Server für diese beiden Anforderungen unterschiedliche Antworten zurückgegeben hat. Im ersten Fall war die Antwort leer; im zweiten Fall enthielt es Daten zu anderen Waren mit dem Wort
Telefon im Namen, als hätte der Parameter
ItemName Telefon als Wert. Diese Art von Verhalten ist unter Hackern und Pentestern bekannt und weist auf ein Problem der App bei der Filterung von Benutzereingaben hin, das unter anderem zur SQL-Injection führt.
Mal sehen, warum dies bei einem SQL-Injection-Beispiel passiert. Wenn ein solches Verhalten in einer Webanwendung gefunden wird, ist es sehr wahrscheinlich, dass die Daten für eine SQL-Anforderung mit der Anforderung selbst verknüpft sind. Im ersten Fall haben wir mit
dem Parameter
Phone ' die folgende SQL-Abfrage:
SELECT item FROM items WHERE item_name='Phone''
Offensichtlich wird es aufgrund falscher Syntax nicht ausgeführt und gibt kein Ergebnis zurück. Die zweite Anforderung mit
dem Parameter
Telefon '+' sieht folgendermaßen aus:
SELECT item FROM items WHERE item_name='Phone'+''
Die Syntax ist korrekt, daher werden Waren mit dem Namen
Telefon ausgewählt . Diese Methode zum Erkennen von Schwachstellen hat einen großen Vorteil beim Testen einer durch WAF geschützten Webanwendung. Ein einfaches Anführungszeichen wird von den meisten modernen WAFs nicht als ausreichende Anomalie in einem Parameter angesehen, daher übergeben sie eine Anforderung damit.
Wir haben die Erkennung von Sicherheitslücken beschrieben, aber wie sieht es mit der Umgehung der WAF und der Ausnutzung der Sicherheitslücke aus? Nachdem wir einige Umgehungsstraßen durchlaufen hatten, fanden wir ein Problem in der WAF. Es stellte sich heraus, dass diese WAF anfällig für Sonderzeichen ist, die zu JSON-Parametern hinzugefügt wurden. Wenn wir JSON-Symbole
0x0A, 0x0D (\ r \ n oder carrige reutrn und neue Zeile) im Rohformat ohne Codierung in ein Textfeld einfügen würden, würde die WAF dies tatsächlich übergeben und die Web-App würde dies berücksichtigen Sei korrekt und verarbeite es. Das Problem lag höchstwahrscheinlich im JSON-Parser, der nicht für spezielle Symbole erstellt und JSON bis zu einer Stelle analysiert wurde, an der diese Symbole angezeigt wurden. Daher würde der WAF-Analysator nicht die vollständige Anforderung erhalten, sodass wir nach Sonderzeichen einen beliebigen Angriffsvektor einfügen könnten. Neben dem Zeilenumbruch würden auch andere Zeichen (z. B. NULL-Byte) funktionieren. Infolgedessen könnten wir die folgende Anforderung schreiben, die die WAF ausschalten würde, wenn sie versucht, diese Anforderung zu überprüfen (Zeilenumbruch und Wagenrücklauf wurden durch ihre Textdarstellung ersetzt):
{"request":{"kill-waf":"die0x0A0x0D", "Count":10,"Offset":0,"ItemName":["'+(SELECT 'Phone'+CHAR(ASCII(substring(@@version,1,1))-24))+'"]}}
0x0A und 0x0D sind Rohbytes.Auf diese Weise konnten wir alle Parameter einfach und schnell auf Schwachstellen testen (einige davon wurden in anderen Parametern gefunden). Durch das Umgehen von WAF und das Ausnutzen dieser Injektion konnten wir alle Benutzer der Webanwendung vollständig gefährden.
Die gleichen Probleme wurden auch in
Nemesida WAF gefunden . Der einzige Unterschied besteht darin, dass die Anforderung nicht in JSON-Codierung vorliegt, sondern eine übliche POST-Anforderung mit Parametern ist und ein Parameter als Zahl auf die SQL-Abfrage bezogen wurde. Wenn einige Symbole in einer Anforderung in URL-Codierung platziert wurden, z. B.
% 03% 04, blockiert WAF eine Anforderung. Wenn Symbole jedoch in Rohform ohne URL-Codierung platziert wurden, übersieht WAF diese Anforderung. Es ist erwähnenswert, dass der normale SQL-Ausdruck sowohl in der Anforderung als auch in der vorherigen WAF platziert wurde. Der SQL-Ausdruck war einfach
'UNION SELECT' ohne zusätzliche Verschleierung, was bedeutet, dass WAF die Anforderung einfach nicht korrekt analysieren und die Analyse weitergeben konnte. Es gibt jedoch ein Problem: Wie kann die SQL-Abfragesyntax korrigiert werden? Weil die Verwendung von Sonderzeichen wie
% 03% 04 in SQL-Abfragen nicht korrekt ist. Die Antwort ist einfach - wir müssen nur Kommentare / ** / verwenden. Die Ergebnisanforderung sah also so aus:
1 UNION SELECT version(), user()
0x03 und 0x04 sind Rohbytes.Ein weiteres Problem wurde in Nemesida WAF gefunden. Es war mit einer fehlerhaften Verarbeitung von POST-Anfragen mit mehrteiligen / Formulardaten verbunden. Wie unten beschrieben, ist bei einer HTTP-Anforderung mit mehrteiligen / Formulardaten die Parametergrenze für die Trennung verschiedener Parameter im Hauptteil einer Anforderung zuständig. Laut RFC muss vor jedem neuen POST-Parameter eine zuvor festgelegte Grenze mit einem Präfix mit
"-" gesetzt werden, damit der Server die verschiedenen Parameter einer Anforderung unterscheiden kann.
Das Problem war also, dass der Server und die WAF die Situation unterschiedlich handhabten, wenn der Grenzparameter leer war. Basierend auf dem RFC ist in einer solchen Situation die Grenze zwischen den Parametern eine Folge von Zeichen
"-" . WAF verwendete jedoch einen Parser, der diese Funktion nicht berücksichtigt. Aus diesem Grund hat WAF die Anforderung erneut übergeben, da die Daten aus den POST-Anforderungsparametern einfach nicht in das Analysemodul gelangt sind und der Server diese Situation ohne Probleme analysiert hat und übertrug die Daten weiter zur Verarbeitung. Dies ist eine Beispielanforderung für diesen Angriff:
POST /wp-content/plugins/answer-my-question/modal.php HTTP/1.1 Host: example.com Content-Type: multipart/form-data; boundary= Content-Length: 209 -- Content-Disposition: form-data; name="id" 1 UNION SELECT 1,2,3,CONVERT(version() USING utf8) AS name,CONVERT(user() USING utf8) AS name,6,7,8,9,10,11,12 FROM wp_users WHERE id=1 ----
Beide Probleme wurden Pentestit gemeldet, die Jungs zahlten eine Belohnung für ihr Bug-Bounty-Programm für Nemesida WAF und behebten die Probleme so schnell wie möglich. Danke ihnen dafür.
Wie wir sehen können, mögen WAFs modern und intelligent sein, aber manchmal ist es möglich, sie zu umgehen, indem nur ein einziges Sonderzeichen hinzugefügt wird. Heutzutage können wir nicht alle möglichen Arten von Eingabedaten für alle Server in der Entwicklungsphase vorhersehen, und maschinelles Lernen, das genau dafür implementiert wurde, stößt auf Parser, die mit Sonderzeichen hängen bleiben.
Fazit

Sollen wir uns also ganz auf WAF verlassen?
Die Antwort lautet NEIN.Bei einem unserer Audits haben wir einen WAF-Bypass entdeckt, mit dem wir einige Schwachstellen ausnutzen konnten. Wie sich herausstellte, hatten die Entwickler bereits eine Prüfung der Web-App durchgeführt, bevor sie von WAF geschützt wurde, und es wurden dieselben Sicherheitslücken aufgedeckt. Anstatt sie zu reparieren, entschieden sie sich für einen modernen WAF mit maschinellem Lernen. Es ist schade, dass der Anbieter der WAF nicht darauf bestand, die Sicherheitslücken zuerst zu beheben. oder vielleicht dachten die Entwickler selbst, dass WAF eine bessere Option wäre. Wir wissen es jedoch nicht genau. In beiden Fällen ist dies ein Beispiel für eine sehr schlechte Vorgehensweise sowohl der Entwickler als auch des Anbieters. Es sollte auch beachtet werden, dass maschinelles Lernen immer noch eine Black Box ist und eher wie ein Marketinginstrument als wie eine echte Verteidigung aussieht.
Im Allgemeinen ist WAF eine moderne Sicherheitslösung, und es schadet nicht, sie mit Ihren Webanwendungen zu haben. Obwohl es heute nur den Prozess der Suche und Ausnutzung von Sicherheitslücken behindern kann, kann es nicht vollständig vor ihnen schützen. Aus heutiger Sicht ist dies seit einiger Zeit Stand der Technik. Sicherheitslücken in Web-Apps können nur durch Korrigieren des zugehörigen Codes behoben werden. Dies ist die einzige narrensichere Lösung.
MitwirkendeIlia Bulatov barracud4Denis Rybin thefaeriedragonAlexander Romanov web_rock