mercoledì 21 settembre 2016

Code Injection Reversing

Code Injection nei siti web

Oggi ho dovuto ripristinare l'ennesimo sito Wordpress bucato. Ormai non è una novità: la qualità del codice dei plugin e dei temi per Wordpress in troppi casi è decisamente bassa e ciò espone numerose vulnerabilità sfruttabili da remoto con estrema facilità.

Spesso, a prescindere dal vettore e dalla tecnica di attacco, l'obiettivo di chi sfrutta queste problematiche di sicurezza è quello di inserire del codice JavaScript arbitrario all'interno dei siti colpiti, ovvero effettuare una code injection.

In particolare questo codice può essere inserito in due modi:
  1. Modificando dei file del sito.
  2. Direttamente nel database.
Nel primo caso è relativamente facile identificare la manomissione. Ad esempio basta tenere sotto controllo i file e confrontarli con una copia pulita. Volendo, il processo è anche automatizzabile.

L'impressione che ho avuto negli ultimi tempi è stata di una diminuzione di questo genere di code injection a favore della seconda metodologia, quella che prevede l'introduzione del codice direttamente nel database.

Mescolando il codice ai dati utente è infatti molto più difficile trovare i record compromessi.

Ma come ci si accorge che un sito è stato vittima di un attacco?


Solitamente ci si rende conto che un sito web è stato compromesso perché ci sono dei comportamente anomali, ad esempio appaiono dei banner pubblicitari o dei popup non previsti, oppure navigando ci si imbatte in redirect verso siti poco raccomandabili.

Dal momento in cui ci si accorge di un malfunzionamento del sito è facile effettuare un debug delle pagine e trovare degli indizi che permettono di risalire ai file ed ai record infetti anche se a volte il codice inserito nelle pagine è offuscato.

Comunque, nella maggior parte dei casi, si riesce in poco tempo ad eliminare il codice indesiderato.

Sistemi di offuscamento multiplo del codice


Nel sito oggetto di ques'ultima intrusione ho potuto ammirare un simpatico sistema di offuscamento a tre livelli.

Nel database era infatti memorizzato un frammento di codice JS così composto:

<script type='text/javascript'>
 (
   new Function(String.fromCharCode( ... )();
 )
</script>

Al posto dei puntini era presente una funzione i cui caratteri erano stati precedentemente convertiti in Unicode.

La funzione era più o meno così:

var key = 'chiave';
var enced = 'stringa';
function xor_enc(string, key) {
  var res = '';
  for (var i = 0; i < string.length; i++) {
    res += String.fromCharCode(string.charCodeAt(i) ^ key.charCodeAt(i % key.length));
  }

  return res;
}
var dec = xor_enc(atob(enced), key);
(new Function (dec))();

Qui il sistema è leggermente più elaborato: in pratica il codice JS vero e proprio è prodotto da una funzione (la xor_enc()) che ha come parametri una stringa in base-64 decodificata dalla funzione atob() ed una chiave.

La funzione xor_enc() cicla la stringa e per ogni singolo carattere ricompone il codice finale in un modo abbastanza originale.

Ed ecco quindi che verrà ricreata ed eseguita la vera e propria funzione che causerà i reali disturbi al sito ed agli utenti.

Ovviamente evito di divulgare tale codice in quanto lo scopo dell'articolo è fornire un aiuto a chi deve combattere questi fenomeni e non aiutare novelli script kiddies a fare danni.

Come comportarsi in caso di code injection?


Quando si vede un banner o un redirect verso ad un altro sito, il primo test è quello di cercare l'URL sospetto all'interno dei file e del database. Se però l'attaccante ha adottato una tecnica di questo genere la stringa è cammuffata e quindi non si può trovare il record.

Basta quindi cercare stringhe come "new Function", "fromCharCode" o similari all'interno del codice sorgente o del database per scovare rapidamente il codice da rimuovere.

Sicuramente quando un sito viene colpito, oltre a ripulire file e database da codice sospetto è anche necessario aggiornare il software vulnerabile.

La falla spesso si trova proprio nel sito, ma in alcuni casi può anche essere nello stack software del server.

Caso per caso bisognerà stabilire se queste operazioni sono abbastanza per rendere sicuro il sito e l'infrastruttura o se invece si rende necessaria una operazione più consistente. Ad esempio il ripristino di dati di backup o soluzioni analoghe.

Come difendere un sito web da intrusioni?

I consigli per difendere un sito, e più in generale un sistema connesso alla rete, sono sempre gli stessi.

Le best practices per un sistema sicuro ormai dovrebbero ben note agli operatori del settore ma fa sempre bene ricordare i fondamentali come ad esempio:
  • tenere sempre aggiornati i software;
  • ridurre i servizi attivi al minimo indispensabile;
  • adottare password complesse;
  • configurare i servizi in modo che siano sicuri;
  • implementare sistemi di protezione come ad esempio firewall.

Inoltre in molte situazioni dei regolari backup possono fare la differenza.