Ciao a tutti,

mentre facevo delle prove su un’installazione Joomla! vecchia (Joomla! 1 per 
l’esattezza) ho notato una
cosa interessante nella gestione delle sessioni. In pratica Joomla! 1 ha una 
tabella nel database chiamata
#__session nella quale salva una sessione attiva per un utente. Nella tabella 
#__session
c’è una colonna chiamata session_id. Inizialmente ho pensato che memorizzasse 
il valore del cookie che viene restituito
al browser in fase di login, ma dopo aver controllato mi sono accorto che non è 
così.
Ho guardato un po’ il sorgente di Joomla e ho notato che le sessioni vengono 
create in maniera diversa rispetto a
quanto pensassi.

La funzione generateId() genera un ID univoco. Per farlo, prima genera un 
numero “pseudo casuale” $randnum e poi
usa questo valore per generare un valore $new_session_id che, per farla breve, 
altro non è che il risultato di alcune
concatenazioni di stringhe (tipo IP e user-agent) e operazioni md5( md5() ).
Per finire, il valore $randnum viene usato come valore del cookie di sessione 
mentre $new_session_id è quello che viene
salvato dentro al database.

> function generateId() {
>          $failsafe       = 20;
>          $randnum        = 0;
> 
>          while ($failsafe--) {
>                  $randnum                = md5( uniqid( microtime(), 1 ) );
>                  $new_session_id = mosMainFrame::sessionCookieValue( $randnum 
> );
>                  file_put_contents("/tmp/jj_log.txt","tbl 
> sessioni?\n",FILE_APPEND);
>                  file_put_contents("/tmp/jj_log.txt",$this->_tbl." _ 
> ".$this->_tbl_key."\n",FILE_APPEND);
> 
>                  if ($randnum != '') {
>                          $query = "SELECT $this->_tbl_key"
>                          . "\n FROM $this->_tbl"
>                          . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( 
> $new_session_id )
>                          ;
>                          $this->_db->setQuery( $query );
>                          if(!$result = $this->_db->query()) {
>                                  die( $this->_db->stderr( true ));
>                          }
> 
>                          if ($this->_db->getNumRows($result) == 0) {
>                                  break;
>                          }
>                  }
>          }
> 
>          $this->_session_cookie  = $randnum;
>          $this->session_id               = $new_session_id;
>  }


Come risultato, nel caso un attaccante riuscisse a trovare una SQL-Injection 
avrebbe molta difficoltà nel riuscire a
proseguire con un attacco di session hijacking perché il valore salvato nel 
database non è quello che è viene inviato
come cookie al browser.

Nella versione 3.x (non ho controllato il sorgente però) il valore del cookie 
che viene inviato al browser
è lo stesso che viene salvato nel database. Come risultato, la presenza di un 
SQL-Injection comporta la possibilità di fare
session hijacking abbastanza facilmente, così come riportato qui:

https://www.trustwave.com/Resources/SpiderLabs-Blog/Joomla-SQL-Injection-Vulnerability-Exploit-Results-in-Full-Administrative-Access/?page=1&year=0&month=0
 
<https://www.trustwave.com/Resources/SpiderLabs-Blog/Joomla-SQL-Injection-Vulnerability-Exploit-Results-in-Full-Administrative-Access/?page=1&year=0&month=0>

Questa cosa mi ha fatto pensare a come mai una versione di Joomla vecchia di 10 
anni sembri essere più sicura di una
recente (almeno per session hijacking in caso di SQL-Injection), e soprattutto 
non basterebbe far
gestire le sessioni, ad esempio, a session_start() del PHP?

Ho provato a chiedere questa cosa anche sul forum Joomla ma non ho avuto molto 
successo :-)
http://forum.joomla.org/viewtopic.php?f=714&t=929239&p=3415676#p3415676 
<http://forum.joomla.org/viewtopic.php?f=714&t=929239&p=3415676#p3415676>

Cosa ne pensate?


Ciao,
Federico.


Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Rispondere a