venerdì 15 marzo 2013

SQL Injection: Rubare Informazioni Da Un Database - Parte 3

Tutto è stato predisposto per estrarre le informazioni dal database. Nelle precedenti guide ci siamo accertati della vulnerabilità del sito e abbiamo ottenuto il numero il numero di colonne selezionate dalla query della pagina. Ora non resta che l'estrapolazione vera e propria dei dati, praticamente non faremo altro che modificare la query in modo da visualizzare le informazioni che ci interessano.

Useremo l'operatore UNION ALL che unisce due risultati. Facciamo un esempio pratico: abbiamo la query A che restituisce i valori "Albero", "Rodrigo", "Mare" e la query B che restituisce i valori "Ladro", "Birra", "Dardo". Il risultato dell'espressione query A UNION ALL query B sarà "Alberto", "Rodrigo", "Mare", "Ladro", "Birra", "Dardo". Si noti che le due query devono restituire lo stesso numero di numero di risultati, ecco perchè ci serviva tanto sapere il numero di colonne selezionate (attraverso l'operatore ORDER BY) dalla query.

Ipotizziamo che la query sia "SELECT * FROM tb_news WHERE id = 1" ed il numero di colonne selezionate sia pari a 6 e noi unissimo questa query a "SELECT 1,2,3,4,5,6" attraverso UNION ALL. Entrambe le query restituiscono 6 risultati che sono quelli presi dalla tabelle delle news (riferendoci all'esempio della seconda parte) più i numeri da 1 a 6. Quindi se scrivessimo nel form GET di id la stringa "1 UNION ALL SELECT 1,2,3,4,5,6--" (ovviamente invece che a 6 dovrete arrivare al numero di colonne che avete trovato quando avete letto la seconda guida) e il sito fosse vulnerabile a questo metodo dovrebbero apparire dei numeri al posto di alcune informazioni della news. Se così non fosse significa che il sito non è vulnerabile a questo metodo, tuttavia consiglio vivamente di non saltare questa parte di guida perché contiene informazioni necessarie da assimilare. Nel prossimo articolo vedremo un metodo alternativo a questo.


Ammettiamo che il numero o uno dei numeri che apparirà sia il 3. Iniettiamo la stringa "1 UNION ALL SELECT 1,2,@@version,4,5,6--". Da notare che al posto del numero 3 abbiamo inserito @@version che è una funzione che restituisce la versione del database. Se andiamo a controllare nella news dove prima c'era il 3 ora c'è la versione. Il meccanismo, quindi, è questo: invece di uno dei numeri che appariranno (in questo caso il 3) andremo a visualizzare delle informazioni dal database.

Andando avanti se vogliamo sapere i nomi di tutte le tabelle basta iniettare la stringa "1 UNION ALL SELECT 1,2,table_name,4,5,6 FROM information_schema.tables--". Information_schema.tables è una tabella che contiene i nomi e le informazioni di tutti le altre tabelle da cui abbiamo selezionato il campo table_name che rappresenta il nome di ognuna.

Segniamoci il nome della tabella da cui ci interessa estrarre dati, ad esempio potrebbe essere users. Iniettiamo la stringa "1 UNION ALL SELECT 1,2,column_name,4,5,6 FROM information_schema.columns WHERE table_name = char(117,115,101,114,115)--". A cosa corrisponde char(117,115,101,114,115)? Corrisponde alla parola users, ogni numero è il decimale assegnato al carattere seguendo la tabella ASCII (tabella standard in cui ad ogni carattere corrisponde un numero). 117, corrisponde alla u, 115 alla s, 101 alla e, così via fino a formare la parola users. I caratteri vengono uniti dalla funzione char(). Se andate sul sito AsciiTable potrete vedere ad ogni carattere (che si trova nella colonna Char) quale decimale (della colonna Dec) è assegnato e poter comporre la vostra parola. Nella stringa di sopra information_schema.columns contiene le colonne di tutte le tabelle ma andremo a selezionare solo la tabella users (o chi per essa) grazie alla condizione "WHERE table_name = char(117,115,101,114,115)--".

Segniamoci il campo (o colonna) che ci interessa sapere (ad esempio name) ed iniettiamo la stringa "1 UNION ALL SELECT 1,2,group_concat(name, 0x2c),4,5,6 FROM users--". Abbiamo selezionato name dalla tabella users (in questo caso deve essere scritta in lettere e non in decimali ASCII) ed unisce i risultati con la funzione group_concat() separandoli con una virgola (ovvero 0x2c). Voilà! Ecco tutti i valori del campo name della tabella users del database.

Mi rendo conto della difficoltà nel capire questa parte ma è fondamentale per il proseguo, di conseguenza consiglio di leggere più volte questo articolo fin quando non appare completamente chiaro.

< Seconda Parte | Quarta Parte (non disponibile) >

8 commenti:

  1. Ciao ; intanto Grazie per le informazioni e quindi per prevenire e aumentare la sicurezza ;

    non sono un addetto ai lavori ma posso assicurarti che ad oggi è quasi impossibile trovare un sistema che ritorni numeri dalla query

    1 UNION ALL SELECT 1,2,3,4,5,etc.....


    in caso contattami in pvt

    RispondiElimina
    Risposte
    1. Tani siti sono vulnerabili ad SQL injection, soprattutto quelli che non fanno parte di una piattaforma.

      Elimina
    2. Grazie mille;

      scusa se ti rispondo solo adesso ma sono stato 15 giorni senza connessione ;)

      Elimina
  2. Se il sito non è vulnerabile a questo tipo di attacco, che altre tecniche ci sono?

    RispondiElimina
  3. Grazie per la guida,sei stato molto chiaro

    RispondiElimina
  4. Non riesco a far funzionare l'ultimo passaggio ????

    RispondiElimina