Dieser Artikel wurde maschinell übersetzt.

Security Briefs

Denial-Of-Service-Angriffe mit regulären Ausdrücken und Schutzmaßnahmen

Bryan Sullivan

In der Ausgabe vom November 2009 schrieb ich einen Artikel mit dem Titel “ XML Denial der Service-Angriffe und Schutzmaßnahmen ” (MSDN.Microsoft.com/magazine/ee335713), in denen einige besonders wirksame des Typs Denial-of-Service (DoS) Angriffstechniken für XML-Parser beschriebenen. Ich empfangen e-Mail-Nachrichten zu diesem Artikel eine Menge von Lesern, mehr wissen möchten, die wirklich ermutigt mich, die Menschen verstehen, wie schwerwiegend DoS-Angriffe sein können.

Ich glaube, dass in den nächsten vier bis fünf Jahren als Berechtigungsweitergabe Angriffe schwieriger auszuführende aufgrund von erhöhten Übernahme von Speicher Schutzmechanismen, z. B. Datenausführungsverhinderung (Data Execution Prevention, DEP), Address Space Layout Randomization (ASLR), Isolation und Privileg Verringerung der Techniken, Angreifer gegenüber DoS-Blackmail-Angriffen deren Fokus verschoben werden. Entwickler können Ihre Anwendungen schützen, indem Sie Aufrechterhalten der Angriff Trend voraus und mögliche zukünftige DoS Vektoren heute Adressierung weiter.

Eine von diesen möglichen zukünftigen DoS Vektoren ist der reguläre Ausdruck DoS. An der OWASP (Open Web Application Security Project) Israel Conference 2009, Checkmarx Chief Architect Alex Roichman und leitender Programmer Adar Weidman dargestellt einige hervorragende Forschung auf das Thema des regulären Ausdrucks DoS oder “ ReDoS. ” Ihre Untersuchungen offen gelegt, dass ein schlecht geschriebenen regulärer Ausdruck ausgenutzt werden kann, so dass eine relativ kurze Angriff-Zeichenfolge (weniger als 50 Zeichen), Stunden oder länger zum Auswerten nutzen kann. Im schlimmsten Fall wird die Verarbeitungszeit tatsächlich exponentiell, um die Anzahl der Zeichen in der Eingabezeichenfolge, d. h., dass das Hinzufügen eines einzelnen Zeichens der Zeichenfolge die Verarbeitungszeit verdoppelt.

In diesem Artikel werde ich beschreiben, was einen Regex für diese Angriffe anfällig macht. Ich wird auch Code darstellen, für einen Regex Fuzzer ein Test-Dienstprogramm anfällig Regexes identifiziert, indem Sie für Tausende von zufällige Eingaben auswerten und kennzeichnen, ob alle Eingaben zum Abschließen der Verarbeitung einer unannehmbar lange dauern.

(Hinweis: In diesem Artikel wird vorausgesetzt, ich Sie mit der Syntax von regulären Ausdrücken vertraut sind. Wenn dies nicht der Fall ist, sollten Sie den Artikel “.NET Framework Regular Expressions” am frischen MSDN.Microsoft.com/library/hs600312, oder lesen Sie für eine tiefer gehende Jeffrey Friedl hervorragende Referenz Buch “ Mastering Regular Expressions 3rd Edition ” [O’Reilly, 2006].)

Backtracking: Das Stammverzeichnis des Problems

Es gibt im Wesentlichen zwei Arten der reguläre Ausdruck Module: Deterministisch DFA (Finite Automaton)-Module und NFA (nicht deterministische Finite Automaton)-Module. Eine umfassende Analyse der Unterschiede zwischen diesen beiden Modul würde den Rahmen dieses Artikels sprengen; wir müssen nur zwei Fakten konzentrieren:

  1. NFA-Module sind backtracking Module. Im Gegensatz zu DFAs, die jedes Zeichen in einer Eingabezeichenfolge höchstens einmal ausgewertet wird, können NFA-Module jedes Zeichen in einer Eingabezeichenfolge mehrmals ausgewertet werden. (Ich werde später aufzuzeigen, wie dieser backtracking Auswertung Algorithmus funktioniert.) Backtracking Ansatz hat Vorteile, darin, dass diese Module regular mehr komplexe Ausdrücke, z. B. mit Rückverweisen oder umschließender Klammern verarbeiten können. Er hat auch Nachteile, darin, dass die Verarbeitungszeit, die von DFAs weit überschreiten kann.
  2. Die Microsoft .NET Framework System.Text.RegularExpression-Klassen verwenden NFA-Module.

Wichtige Nebeneffekt backtracking ist, während das Regex-Modul eine positive Übereinstimmung ziemlich schnell bestätigen kann (d. h., eine Eingabezeichenfolge entspricht einen bestimmten Regex), bestätigen eine negative Übereinstimmung (die Eingabezeichenfolge entspricht nicht der Regex) Recht etwas länger dauern kann. Tatsächlich muss das Modul zu bestätigen, dass keine der möglichen “ Pfade ” durch die Eingabezeichenfolge die Regex übereinstimmt, so dass alle Pfade, die getestet werden müssen.

Mit einem einfachen nicht Gruppierung regulären Ausdruck ist der Zeitaufwand, um negative Übereinstimmungen zu bestätigen, kein großes Problem. Nehmen wir beispielsweise an, dass der reguläre Ausdruck, der verglichen werden ist:

^\d+$

Hierbei handelt es sich um ein relativ einfaches Regex, der erfüllt, wenn die gesamte Eingabezeichenfolge nur numerische Zeichen besteht. Die ^ und $ Zeichen repräsentieren den Anfang und Ende der Zeichenfolge, die Ausdruck \d ein numerisches Zeichen darstellt und + gibt an, dass ein oder mehrere Zeichen entsprechen werden. Dieser Ausdruck einer Eingabezeichenfolge unter 123456X Let’s zu testen.

Dieser Eingabezeichenfolge ist offensichtlich keine Übereinstimmung, da X nicht numerisches Zeichen ist. Aber wie viele Pfade würde die Regex-Beispiel auswerten zu diesem Schluss kommen? Es seine Auswertung am Anfang der Zeichenfolge zu starten, und sehen, dass das Zeichen 1 ein gültiges numerische Zeichen ist, und der Regex entspricht. Es würde dann zum Zeichen 2 verschieben auf die auch übereinstimmen würde. Der Regex hat daher an dieser Stelle die Zeichenfolge 12 übereinstimmt. Als Nächstes es würde versuchen 3 (und 123 übereinstimmen), und so weiter bis x, erhielt die nicht übereinstimmen würden.

Jedoch, da unsere-Modul eine NFA Rückverfolgungsmodul ist, ist es nicht zu diesem Zeitpunkt aufzugeben. Stattdessen erstellt eine Sicherungskopie von seiner aktuellen Übereinstimmung (123456) der letzten bekannten guten Übereinstimmung (12345) und von dort aus erneut versucht. Da das nächste Zeichen nach 5 nicht das Ende der Zeichenfolge befindet, den Regex ist keine Übereinstimmung, und es auf seinen vorherigen letzten bekannten guten Übereinstimmung (1234) gesichert und erneut versucht. Dies wird ganz, bis das Modul wieder an die erste Übereinstimmung (1 ruft) und das Zeichen findet nach 1 nicht das Ende der Zeichenfolge fortgesetzt. Zu diesem Zeitpunkt die Regex einrichten kann, keine Übereinstimmung gefunden wurde.

Das Datenbankmodul ausgewertet alles in allem sechs Pfade: 123456, 12345, wie 1234, 123, 12 und 1. Wenn die Eingabezeichenfolge ein Zeichen, die länger ist, hat das Modul würde eine weitere Pfad ausgewertet. Damit dieser reguläre Ausdruck eine lineare Algorithmus für die Länge der Zeichenfolge ist und nicht Gefahr, verursacht eine Dienstverweigerung. Eine System.Text.RegularExpressions.Regex-Objekt mit ^ \d+$ nach dessen Muster ist schnell genug, um über auch enorme Eingabezeichenfolgen (mehr als 10.000 Zeichen) praktisch sofort abgebrochen.

Jetzt ändern Sie den regulären Ausdruck let’s in Gruppe auf numerischen Zeichen:

^(\d+)$

Dadurch wird das Ergebnis der Auswertungen nicht erheblich geändert; es einfach den Entwickler, die Übereinstimmung als erfasste Gruppe zugreifen kann. (Diese Technik kann in regulären Ausdrücken komplizierter hilfreich sein könnten Wiederholung Operatoren angewendet werden soll, aber in diesem speziellen Fall keinen Wert enthält.) Einfügen von runden Klammern Gruppierung ändert in diesem Fall wesentlich Ausführungsgeschwindigkeit des Ausdrucks, entweder sich nicht. Testen das Muster für die Eingabe 123456X wird weiterhin das Modul nur sechs verschiedene Wege auswerten. Die Situation ist jedoch deutlich anders, wenn wir eine weitere kleine Änderung an den Regex vornehmen:

^(\d+)+$

Die zusätzlichen + Zeichen, nachdem der Gruppenausdruck (\d+) die Regex-Engine für eine beliebige Anzahl der aufgezeichneten Gruppen informiert. Das Datenbankmodul verläuft wie zuvor zu 123456 vor, 12345 backtracking abrufen.

Hier ist, wobei Dinge “ ” interessant (wie in horribly gefährliche). Statt einfach überprüfen, dass das nächste Zeichen nach 5 nicht das Ende der Zeichenfolge, das Modul das nächste Zeichen behandelt, 6, als eine neue Aufzeichnung gruppieren und beginnt dort rechecking. Sobald dieser Route fehlschlägt, bis zu 1234 sichert und versucht dann 56 als separate Capture Gruppe und dann 5 und 6 jeweils als separate Capture-Gruppen. Das Endergebnis ist, dass das Datenbankmodul tatsächlich Ausgangszeile 32 verschiedene Wege auswerten.

Wenn wir jetzt nur eine weitere numerisches Zeichens der Zeichenfolge Auswertung hinzugefügt haben, wird das Modul zum Auswerten von 64 Pfade haben – doppelt so viele – um zu bestimmen, dass es sich nicht um eine Übereinstimmung handelt. Hierbei handelt es sich um einen exponentiellen Anstieg in den Umfang der Arbeit vom Regex-Modul ausgeführt wird. Ein Angreifer könnte eine relativ kurze Eingabezeichenfolge bereitstellen – 30 Zeichen oder dies – und erzwingen Sie das Modul an Prozess Hunderte von Millionen von Pfaden, die für Stunden oder Tagen zu binden.

Ausgestrahlt des Dirty Wäsche

Es ist schlecht ausreichend, wenn eine Anwendung DoS können exponentiell Regexes in serverseitigem Code sofort versteckt hat. Es ist schlimmer noch, wenn eine Anwendung die Sicherheitsanfälligkeiten in clientseitigen Code kündigt. Viele der ASP.NET Validator-Steuerelemente, die von System.Web.UI.WebControls.BaseValidator, einschließlich RegularExpressionValidator, abgeleitet werden automatisch die gleiche Überprüfungslogik auf dem Client in JavaScript auszuführen, wie auf dem Server in .NET-Code.

In den meisten Fällen, ist dies eine gute Sache. Es ist gut zum Speichern des Benutzers der Round-Trip Uhrzeit eine Formularsendung an den Server genau so, dass Sie nach einer Bestätigung zurückgewiesen, da der Benutzer ein Eingabefeld falsch eingegeben. Es ist ratsam, die Verarbeitungszeit des Servers zu speichern. Allerdings Wenn die Anwendung einen falschen Regex in seiner Servercode verwendet, die fehlerhafte Regex geht auch in den Clientcode verwendet werden und jetzt werden extrem einfach für einen Angreifer dieses Regex zu finden und eine Angriff Zeichenfolge dafür entwickeln.

Genommen Sie an, ich ein neues Web Form erstellen und ein Textfeld-Steuerelement (TextBox) und ein RegularExpressionValidator-Steuerelement auf dieses Formular hinzuzufügen. Legen Sie die Bestätigung ControlToValidate-Eigenschaft auf den Namen des Textfeldes, und legen Sie seine ValidationExpression für eine der fehlerhaften Regexes erwähnt habe:

this.RegularExpressionValidator1.ControlToValidate = "TextBox1";

this.RegularExpressionValidator1.ValidationExpression = @"^(\d+)+$";

Wenn ich jetzt auf dieser Seite in einem Browser öffnen und die Quelle anzeigen, sehe ich nahe an den unteren Rand der Seite den folgenden JavaScript-Code:

<scripttype="text/javascript">

//< ![CDATA[

var RegularExpressionValidator1 = document.all ? 

  document.all["RegularExpressionValidator1"] : 

  document.getElementById("RegularExpressionValidator1");

RegularExpressionValidator1.controltovalidate = "TextBox1";

RegularExpressionValidator1.validationexpression = "^(\\d+)+$";

//]] >

</script>

Es gibt es für die ganze Welt um finden Sie unter: die exponentielle Regex im einfachen Blick auf die letzte Zeile des Skriptblocks.

Weitere Fehler Muster

Natürlich ^(\d+)+$ is not the only bad regular expression in the world. Alle regulärer Ausdruck mit einem Gruppierungsausdruck mit Wiederholung, die selbst die wiederholt wird jetzt im Grunde anfällig sein. Dazu gehören z. B. Regexes:

^(\d+)*$
^(\d*)*$
^(\d+|\s+)*$

Darüber hinaus ist eine beliebige Gruppe mit der Alternierung, in dem die alternative Teilausdrücke überlappen, auch anfällig:

^ (\d|\d\d)+$
^(\d|\d?)+$

Wenn Sie einen Ausdruck wie im vorherigen Beispiel in Ihrem Code haben nun gesehen, würden Sie wahrscheinlich als nur aus betrachten ihn anfällig zu identifizieren können. Aber Sie können eine Sicherheitsanfälligkeit in einem längeren verpassen Ausdruck komplexere (und realistischere):

^ ([0-9a-zA-Z]([-. \w]*[0-9a-zA-Z])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+ [a-zA-Z] {2,9}) $

Hierbei handelt es sich um einen regulären Ausdruck gefunden wird, auf das Regular Expression Website Library (regexlib.com), die verwendet werden, um eine e-Mail-Adresse zu überprüfen. Es ist jedoch auch anfällig für Angriffe. Fanden Sie diese Sicherheitsanfälligkeit über manuelle Code-Prüfung, oder Sie ist möglicherweise nicht. Eine einfachere Methode, um diese Probleme zu finden ist erforderlich, und, was ich werde als Nächstes erläutert wird.

Ungültige Regexes Suchen in Ihren Code

Im Idealfall würde eine Möglichkeit, exponentielle Regexes im Code bei der Kompilierung und Warnen Sie Sie zu finden sein. Um eine Regex-Zeichenfolge zu analysieren und für potenzielle Schwachstellen zu analysieren, vermutlich, benötigen Sie einen weiteren Regex. Zu diesem Zeitpunkt fühle ich wie ein Regex-Addict: “ Ich Don ’t benötigen Sie Hilfe, ich brauche nur weitere Regexes! ” Meine Fähigkeiten Regex sind leider nicht bis zu der Aufgabe einen Regex zur Analyse von Regexes zu schreiben. Wenn Sie, glauben Sie haben Arbeit für diesen code, der an mich senden, und ich werde zufrieden geben, haben Sie im nächsten Monat Security Briefs-Spalte. In der Zwischenzeit da ich Don ’t eine Möglichkeit, fehlerhafte Regexes zur Kompilierzeit erkannt haben, werde ich nächsten Sie am besten: Ein Regex Fuzzer werde geschrieben werden.

Fuzzing ist der Prozess der zufällige, fehlerhafte Daten an eine Anwendung Eingaben zu erleichtern fehlschlagen bereitstellt. Mehr fuzzing Iterationen Sie ausführen, desto bessere die Möglichkeit, die Sie einen Fehler feststellen werden, daher ist es üblich, dass Teams Tausende oder Millionen von Iterationen pro Eingabe ausgeführt. Microsoft-Sicherheitsteams ist dies eine unglaublich effektive Möglichkeit, Fehler, zu finden, sodass Security Development Lifecycle-Team hat eine Anforderung für alle Produkte und Dienste Teams fuzzing werden gefunden.

Für meine Fuzzer zufällige Eingabezeichenfolgen auf Meine regulären Ausdruck mit zufälligen Daten werden soll. Ich beginne durch Definieren einer const Zeichenfolge für meine Regex eine TestInputValue-Methode, die die Regex überprüft und eine RunTest-Methode, die die zufällige erfasst Eingabe Zeichenfolgen auf, um TestInputValue einzulegen.

const string regexToTest = @"^(\d+)+$";



static void testInputValue(string inputToTest)

{

  System.Text.RegularExpressions.Regex.Match(inputToTest, regexToTest);

}



void runTest()

{

  string[] inputsToTest = {};



  foreach (string inputToTest in inputsToTest)

  testInputValue(inputToTest);

}

Beachten Sie, dass kein Code noch an die fuzzed Eingabewerte generieren; Ich rufe später mit dem in Kürze. Beachten Sie außerdem, dass der Code zum Überprüfen des Rückgabewerts von Regex.Match kümmern nicht. Dies liegt daran, dass ich tatsächlich sorgt nicht, ob die Eingabe dem Muster entspricht. Ich in diesem Fall wichtig sind lediglich, ob die Regex-Engine dauert zu lange, entscheiden Sie, ob die Eingabe entspricht.

Normalerweise Fuzzer werden verwendet, um ausnutzbare Privileg Erhöhung Sicherheitslücken zu suchen, aber auch in diesem Fall bin ich nur interessiert DoS Sicherheitslücken suchen. Ich kann nicht einfach meine Anwendung Testdaten um festzustellen, ob er stürzt feed, habe ich in der Lage zu erkennen, ob es, nach oben gesperrt ist. Obwohl die meisten wissenschaftliche-Methode möglicherweise nicht, erreichen ich effektiv dies, indem jeder Test Regex sequenziell ausgeführt, auf einem separaten Arbeitsthread und einen Timeoutwert für den Abschluss des Threads festlegen. Wenn der Thread nicht innerhalb einer angemessenen Zeit, die dessen Verarbeitung abgeschlossen fünf Sekunden zum Testen einer einzelnen Eingabe beispielsweise ist davon ausgehen, dass wir, dass der reguläre Ausdruck wurde DoS würden. Ich werde ein ManualResetEvent hinzufügen und ändern Sie die TestInputValue und RunTest-Methode wie in entsprechendAbbildung 1.

Abbildung 1 Testen mithilfe von separaten Workerthreads

static ManualResetEvent threadComplete = new ManualResetEvent(false);



static void testInputValue(object inputToTest)

{

  System.Text.RegularExpressions.Regex.Match((string)inputToTest, 

    regexToTest);

  threadComplete.Set();

}



void runTest()

{

  string[] inputsToTest = {};



  foreach (string inputToTest in inputsToTest)

  {

    Thread thread = new Thread(testInputValue);

    thread.Start(inputToTest);



    if (!threadComplete.WaitOne(5000))

    {

      Console.WriteLine("Regex exceeded time limit for input " + 

        inputToTest);

      return;

    }



    threadComplete.Reset();

  }



  Console.WriteLine("All tests succeeded within the time limit.");

}

Jetzt ist es Zeit für die Eingabewerte generieren. Dies ist tatsächlich schwieriger, als es klingt. Wenn ich nur vollständig Zufallsdaten generieren, ist es unwahrscheinlich, dass es genügend Regex um eine Sicherheitsanfälligkeit anzuzeigen entsprechen würde. Angenommen, ich teste das Regex ^ (\d+)+$ mit der Eingabe XdO(*iLy@Lm4p$, the regex will instantly not match and the problem will remain hidden. Muss ich Eingaben generieren, die relativ nahe an welche die Anwendung erwartet, damit der Test nützlich sein, und ich benötigen eine Möglichkeit zum Generieren von Zufallsdaten, die einen bestimmten Regex entspricht.

Datengenerierungspläne an die Rescue

Glücklicherweise ist ein Feature in Visual Studio-Datenbank-Projekte, die genau dies tun können: die Datengenerierung zu planen. Wenn Sie Visual Studio Team Suite verwenden, haben Sie auch Zugriff auf dieses Feature. Datengenerierungspläne werden verwendet, um Datenbanken schnell mit Testdaten zu füllen. Sie können Tabellen mit zufälligen Zeichenfolgen oder numerische Werte oder (zum Glück für uns) übereinstimmenden Zeichenfolgen regulärer Ausdrücke angegeben.

Sie müssen zuerst erstellen Sie eine Tabelle in einer SQL Server 2005 oder 2008-Datenbank, die in den Testdaten generiert werden können. Sobald dies geschehen ist, kehren Sie in Visual Studio und erstellen Sie ein neues SQL Server-Datenbank-Projekt. Bearbeiten Sie die Datenbank-Projekteigenschaften, es mit einer Verbindungszeichenfolge zur Datenbank bereitzustellen. Sobald Sie eine Verbindungszeichenfolge eingegeben und getestet, um sicherzustellen, dass Sie funktioniert haben, kehren Sie zurück zum Projektmappen-Explorer, und ein neues Data Generation Plan Element zum Projekt hinzufügen. Zu diesem Zeitpunkt sollte etwa angezeigtAbbildung 2.

Figure 2 A Data Generation Plan Item in Visual Studio
Abbildung 2 Ein Plan für die Datengenerierung-Element im Visual Studio

Wählen Sie nun die Tabellen- und Spaltennamen, die mit Fuzzer Eingabedaten ausgefüllt werden soll. Legen Sie im Tabellenabschnitt „, die Anzahl der Tests generiert Werte werden (die Zeilen auf Spalte einfügen). Zuvor habe ich, dass Fuzzer Hunderttausende oder Millionen von Iterationen, um Probleme zu finden im Allgemeinen testen. Obwohl ich in der Regel für diese Ebene strenge genehmigen, ist es nicht sinnvoll, für die Zwecke dieses Fuzzer Regex. Wenn ein Regex von Sperren, geht es in ein paar hundert Testiterationen tun. Ich vorschlagen, die Zeilen einfügen-Wert, um 200 festlegen, aber wenn Sie mehrere, testen möchten gerne.

Im Abschnitt Spalte jetzt den Generator auf Regular Expression festgelegt, und geben Sie den Regex-Muster-Wert als der Wert der Expression-Eigenschaft in der Spalte Eigenschaftenregisterkarte überprüft werden sollen. Es ist wichtig zu beachten, dass die Expression-Eigenschaft jedes Zeichen zulässigen regulären Ausdruck nicht unterstützt. Sie können keine Anfang und Ende-of-Line Anchor eingeben ^ und $ (oder präziser, können Sie diese eingeben, aber der Generator generiert ein Literal ^ oder Zeichen in der Testeingabe $). Lassen Sie diese Zeichen aus. Sie finden eine vollständige Liste der Operatoren, die durch den regulären Ausdruck-Generator unter unterstützt MSDN.Microsoft.com/library/aa833197(VS.80).

Ein größeres Problem ist, dass die Expression-Eigenschaft auch allgemeine Kurzschrift Notationen z. B. \d für Ziffern oder \w für Wort Zeichen unterstützt. Wenn diese Ihre Regex verwendet werden, haben Sie Sie durch Ihre Klassenentsprechungen Zeichen ersetzen: [0-9] anstelle von \d "," [a-zA-Z0-9_] anstelle von \w und so weiter. Wenn Sie \s (Whitespace-Zeichen) ersetzen müssen, können Sie ein literal Leerzeichen an seiner Stelle eingeben.

Ihre letzte Aufgabe im Datenbankprojekt ist in die Datenbank tatsächlich mit den Testdaten entsprechend Ihren Angaben zu füllen. Dazu wählen Sie die Daten | DataGenerator | Menüelement Daten generieren, oder drücken Sie einfach die F5.

Der Angriff hinzufügen

Wieder im Code Fuzzer ändern Sie die RunTest-Methode, damit es die generierten Testdaten aus der Datenbank abruft. Sie können sich vorstellen danach fertig, jedoch in der Tat gibt es eine weitere wichtige Änderung vornehmen. Wenn Sie die Fuzzer jetzt sogar über eine bekannte fehlerhafte Regex z. B. ^(\d+)+$, it will fail to find any problems and report that all tests succeeded. ausführen Dies liegt daran, dass alle die Testdaten, die Sie erstellt haben, ist eine gültige Übereinstimmung für die Regex.

Weiter oben erinnern, ich erwähnt, dass NFA-Module für Regex ziemlich schnell eine positive Übereinstimmung und diese Probleme tatsächlich bestätigen können nur auf negative Übereinstimmungen passieren. Darüber hinaus aufgrund der NFAs backtracking, Probleme treten dann auf nur, wenn eine große Anzahl von übereinstimmenden Zeichen am Anfang der Eingabe sind und am Ende wird das falsche Zeichen angezeigt. Wenn ein ungültiges Zeichen am Anfang der Eingabezeichenfolge enthalten war, würde der Test sofort beendet.

Die letzte Änderung am Fuzzer-Code vornehmen, ist das fehlerhafte Zeichen auf die Enden der Test Eingaben anhängen. Stellen Sie ein Zeichenfolgenarray mit numerische, alphabetische, Satzzeichen und Leerzeichen:

 

string[] attackChars = { "0", "1", "9", "X", "x", "+", 

"-", "@", "!", "(", ")", "[", "]", "\\", "/", 

"?", "<", ">", ".", ",", ":", ";", " ", "" };

Ändern Sie den Code jetzt, damit jeder aus der Datenbank abgerufenen Eingabezeichenfolge mit jedem dieser Angriff Zeichen angehängten getestet wird. So würde die erste Eingabezeichenfolge mit einem angehängten, dann mit einem angehängten usw. 1 Zeichen 0 Zeichen getestet werden. Nachdem die Eingabezeichenfolge mit den einzelnen Zeichen Angriff getestet wurde, auf die nächste Eingabezeichenfolge verschieben und mit jedem der Angriff Zeichen zu testen.

foreach (string inputToTest in inputsToTest)

{

  foreach (string attackChar in attackChars)

  {

    Threadthread = new Thread(testInputValue);

    thread.Start(inputToTest + attackChar);

...

Jetzt haben Sie zwei Probleme

Es ist ein berühmten Zitat von Ex Netscape Engineering für Frau Herder bis jetzt einen Zawinski zu reguläre Ausdrücken:

“ Denken, dass einige Personen, wenn bei einem Problem konfrontiert, ‘ ich weiß, ich reguläre Ausdrücke verwendet werden. ’ Jetzt haben Sie zwei Probleme. ”

Während ich nirgends near als zynisch über Regexes als MR. Zawinski, werden ich zugeben, dass es recht schwierig sein kann, nur um einen korrekten Regex viel weniger richtigen Regex zu schreiben, die gegen DoS-Angriffen sicher ist. Ich empfehle Ihnen die um alle Ihre Regexes für exponentielle Komplexität zu untersuchen und fuzzing Techniken verwenden, um Ihre Ergebnisse zu überprüfen.

Bryan Sullivan ist als Security Programmmanager für das Microsoft Security Development Lifecycle-Team, wo er in der Webanwendung und .NET Sicherheitsprobleme spezialisiert. Er ist Autor von “ AJAX Security ” (Addison-Wesley, 2007).

Unser Dank gilt den folgenden technischen Experten für die Durchsicht dieses Artikels: Barclay Hill, Michael Howard, Ron Petrusha und Justin van Patten