Frage:
Ist SQL Injection mit LIMIT möglich?
Ali
2014-12-23 17:04:30 UTC
view on stackexchange narkive permalink

Ein Freund von mir hat eine Webanwendung erstellt, die ich zum Spaß teste. Ich habe festgestellt, dass er einem Benutzer erlaubt, das Limit einer bestimmten Abfrage festzulegen, und dieses Limit ist nicht bereinigt.

Zum Beispiel kann ich eine beliebige Zahl oder Zeichenfolge als Limit auswählen. Mir ist klar, dass dies SQL-Injection ist und ich problemlos SQL-Befehle einfügen kann. Ist es jedoch wirklich möglich, mit einem LIMIT Daten zu extrahieren oder Schäden zu verursachen?

Beispiel für die Abfrage:

  SELECT * FROM Nachrichten WHERE ungelesen = 1 LIMIT ** USER INPUT HERE **  

I. Wenn die Injektion in der Klausel WHERE enthalten wäre, hätte ich leicht eine UNION SELECT durchführen können, um Informationen zu extrahieren. Ist dies jedoch wirklich möglich, wenn die Benutzereingabe nach dem erfolgt? Grenze?

Für weitere Informationen verwendet mein Freund das DBMS MySQL, sodass Sie zwei Abfragen nicht wirklich ausführen können, z. B.:

  SELECT * FROM Nachrichten WHERE ungelesen = 1 LIMIT 10; DROP TABLE Nachrichten--  

Es ist nicht möglich.

Die Dinge haben sich ein wenig geändert. Ich poste ein Update in einer neuen Frage und ändere dieses nicht, wenn man bedenkt, wie viel Aufmerksamkeit es bekommen hat.
Meine Empfehlung beim Auffinden solcher Sicherheitslücken ist, sie zu beheben, unabhängig davon, ob sie ausnutzbar sind oder nicht. Das macht Ihre Frage natürlich nicht irrelevant. Es kann sehr lehrreich sein zu sehen, warum eine scheinbar nicht ausnutzbare Sicherheitslücke sowieso ausgenutzt werden kann. Sollten Sie jemals eine finden, die wirklich nicht ausnutzbar ist, haben Sie wahrscheinlich mehr Zeit damit verbracht, die Ausnutzbarkeit zu analysieren, als sie einfach zu beheben hätten.
Jedes Mal, wenn Sie Unklarheiten haben, bei denen die * Daten * möglicherweise mit dem * Befehl * verwechselt werden, können Probleme auftreten, auch wenn sie schwer zu finden sind.
Wirf es als int und stelle sicher, dass es innerhalb akzeptabler Grenzen liegt. Wenn Ihr Client die Möglichkeit hat, nach Typ (int type) zu binden, tun Sie dies.
"UNION" ist nicht die einzige Sorge, die ich hätte. Was ist mit "DROP TABLE" oder "TRUNCATE TABLE"?
Bei der SQL-Injection geht es nicht nur darum, eingeschränkte Daten zu extrahieren, sondern auch Daten zu beschädigen.
Sechs antworten:
PiTheNumber
2014-12-23 19:12:00 UTC
view on stackexchange narkive permalink

Hier können Sie eine UNION SELECT vornehmen. Das einzige Problem besteht darin, die Spalten aus Nachrichten abzugleichen. Sie können diese jedoch erraten, indem Sie Spalten hinzufügen, bis sie passen:

  SELECT * FROM Nachrichten WHERE ungelesen = 1 LIMIT 1 UNION SELECT Mail, Passwort, 1 , 1,1 FROM Benutzer  

Fügen Sie einfach , 1 hinzu, bis Sie die richtige Spaltenanzahl erhalten. Außerdem müssen Sie dem Spaltentyp entsprechen. Versuchen Sie null anstelle von 1 .

Wenn Sie MySQL-Fehler sehen können, würde dies hier sehr hilfreich sein. Ansonsten haben Sie viel versucht.

Weitere Informationen finden Sie unter Testen auf SQL-Injection unter owasp.org.

Wäre dies möglich, wenn vor dem Limit eine ORDER BY-Anweisung vorhanden wäre?
Dies funktioniert in MySQL 5.7+ nicht, da Sie "UNION" nach "LIMIT" nur verwenden können, wenn die gesamte Abfrage vor "UNION" in Klammern steht.So etwas wie `(SELECT * FROM table LIMIT 1) UNION SELECT ....`.
Dillinur
2014-12-23 20:35:43 UTC
view on stackexchange narkive permalink

Entweder gibt es fast keine Einschränkungen, und Sie können dies auf die übliche Weise tun (UNION oder '; XXX ---').

Manchmal ist dies nicht möglich, und Sie müssen beim Putten zurückgreifen ein boolescher Ausdruck im LIMIT. Dies ist eine blinde SQL-Injection, mit der Sie die gesamte Datenbank bitweise sichern können.

Sie können einen ganzzahligen Ausdruck einfügen und jeweils ein paar weitere Bits extrahieren, vorausgesetzt, die Abfrage generiert eine Liste, die angezeigt wird.
Schwern
2014-12-24 10:27:23 UTC
view on stackexchange narkive permalink

MySQL unterstützt mehrere Anweisungen und hat dies seit mindestens 4.1 vor zehn Jahren getan. Beispielsweise können Sie dies im Perl-MySQL-Modul mit mysql_multi_statements aktivieren.

Während die Clientbibliothek derzeit möglicherweise nicht mehrere Anweisungen unterstützt, können Sie dies tun Es handelt sich lediglich um ein Upgrade oder eine Konfigurationsänderung, die von einer Sicherheitslücke entfernt ist.

Client-Bibliotheken haben aus Sicherheitsgründen die Unterstützung für mehrere Anweisungen * absichtlich entfernt *.
@Mark Zitat? Perls DBD :: mysql ist standardmäßig deaktiviert, aber leicht verfügbar. PHPs [mysqli] (http://php.net/manual/en/mysqli.multi-query.php) erfordert einen speziellen Aufruf. .NETs [ADO] (http://www.codeproject.com/Articles/306722/Executing-multiple-SQL-statements-as-one-against-S) scheint keinen speziellen Code zu erfordern.
user45139
2014-12-23 17:41:58 UTC
view on stackexchange narkive permalink

Die Abfrage Ihres Freundes wäre heute nicht sehr nützlich, könnte aber später sein, aber wenn sich die Technologien weiterentwickeln und MySQL DBMS wie viele andere Technologien ständig verbessert wird, muss Ihr Freund die Eingabe im Fall von LIMIT wird so geändert, dass UNION direkt danach verwendet werden kann. Ihr Freund könnte auch den Fall in Betracht ziehen, in dem die Architektur von MySQL DBMS so geändert wird, dass es möglich ist, mehrere SQL-Anweisungen auszuführen, anders als jetzt.

Was ich sagen möchte, ist das Ihr Freund muss den Input bereinigen: Es ist die beste Vorgehensweise: Sie sehen das heute vielleicht nicht so wichtig, aber in Zukunft wissen Sie es nie und denken Sie daran, dass es immer Menschen gibt, die erfahrener sind als Ihr Freund.

Während einige MySQL-Clients darauf beschränkt sein können, nur eine einzige Anweisung pro Aufruf zuzulassen (dies verhindert den oben beschriebenen Angriff), würde ich es als schlechte Praxis betrachten, sich darauf als einzigen Schutzmechanismus zu verlassen - ähnlich, während MySQL derzeit eine Literal-Ganzzahl nach LIMIT erwartet Es ist möglich, dass es in Zukunft eine Funktion oder Unterabfrage zulässt.
-1 Ein echter Exploit wäre schön.
@Rook Er sagte, die Eingabe von "LIMIT" sei nicht bereinigt, so dass er diesen Befehl auf der Oberfläche der Website ausführen könne, da es ihm gelungen sei, etwas auszuführen. Warum fragst du auch nach einem 100% echten Exploit? Ich weiß nicht einmal, um welche Website es sich handelt
Stapel stapeln? In MySQL? Haben Sie jemals SQL Injection unter MySQL ausgenutzt? PiTheNumber hat die richtige Antwort bekommen.
@Rook Die Person, die die Frage gestellt hat, weiß bereits, dass sie "UNION SELECT Something" verwenden kann (lesen Sie seine Frage). Wenn ich vorher SQL-Injektionen gemacht habe? Wie Sie bereits wissen, niemals (aber ich liebe Ihre Website)
Tut mir leid, aber das ist ein riesiger Pet Peeve von mir. Hauptsächlich, weil ich mir wirklich wünsche, dass das Stapeln von Abfragen von den meisten SQL-Datenbanken unterstützt wird, aber in der realen Welt ist dies sehr ungewöhnlich (MS-SQL, Access, SQLite). Ich sehe Beiträge, die über das Stapeln von Abfragen sprechen, als falsche Hoffnung.
Damian Yerrick
2014-12-24 01:30:30 UTC
view on stackexchange narkive permalink

Festlegen eines Limits von 1 UNION SELECT ... ermöglicht es dem Angreifer, Informationen aus einer anderen Tabelle abzurufen, solange die Spalten CAST code haben (oder sein können) > die gleiche Nummer und den gleichen Typ wie die Spalten im ersten SELECT haben. Wenn Sie einen Grenzwert als Wert festlegen, der aus einem sub- SELECT erzeugt wird, kann der Angreifer jeden anderen lesen Informationen in der Datenbank aus der Anzahl der zurückgegebenen Zeilen. Beispielsweise kann der Kennwort-Hash eines anderen Benutzers 4 Bit gleichzeitig extrahiert werden, indem wiederholt eine Unterabfrage ausgeführt wird, die eine Zahl zwischen 0 und 15 bei verschiedenen Teilzeichenfolgen-Offsets zurückgibt und dann die Zeilen in jeder Zeile zählt Ergebnis.

Beide Angriffe können jedoch vereitelt werden. Viele Datenbanktreiber ermöglichen ein parametrisiertes LIMIT . Wenn ein bestimmter Treiber einen parametrisierten stört LIMIT können Sie die Eingabe bereinigen, indem Sie die Eingabe in eine Ganzzahl konvertieren, bevor Sie sie durch eine Zeichenfolge in die Abfrage einsetzen. Auf diese Weise können Sie auch sicherstellen, dass keine weiteren Datensätze zurückgegeben werden als Ihre Anwendung von einer Abfrage verarbeiten kann (z. B. LIMIT 12345678 ). In PHP könnte dies folgendermaßen aussehen:

  <? php //...$ limit = intval ($ _ REQUEST ['numresults']); $ limit = min (max ($ limit, 10), 100); $ stmt = $ dbh->prepare ("SELECT ... FROM ... WHERE ... LIMIT $ limit ");  
Rick
2014-12-25 09:42:14 UTC
view on stackexchange narkive permalink

Dies ist ein guter Zeitpunkt, um PDO-vorbereitete Anweisungen zu verwenden und diese Variable als reine Ganzzahl-Eingabe zu binden. Das sollte jeden Versuch zunichte machen, was Sie versuchen, indem Sie SQL einfügen.

Ich würde auch in Betracht ziehen, den Benutzer aus einer voreingestellten Liste von Zahlen in einer Dropdown-Liste auswählen zu lassen. Wenn die Ergebnisseite nicht auf Paginierung eingestellt ist, können Sie möglicherweise ein nettes Durcheinander in Ihren Händen haben, wenn Sie versuchen, 100.000 Datensätze auf eine Seite zu laden.



Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...