martedì, settembre 18, 2012

Hack WhatsApp - Un'applicazione vulnerabile by design


Premetto, amo WhatsApp, adoro il fatto che permetta di trasferire messaggi e brevi informazioni ad un costo equo (cioè quasi gratuitamente) rompendo le logiche delle telco che lucrano paurosamente su SMS ed affini (lucravano spero).

Va ricordato, per la cronaca, che WhatsApp è un giocattolo capace di muovere 1 miliardo di messaggi al giorno, ma proprio per questa popolarità è giusto che, in quanto utenti, impariamo a porci alcune domande in merito alla sua affidabilità (questo vale anche per molte altre app a dire il vero).

La prima, da buon paranoico è: Ma quant'è sicuro? Quanto è preservata la riservatezza dei messaggi che girano su quest'app? Poco veramente poco.

Distinguiamo ora due scenari di utilizzo: 1) Rete cellulare 2) Rete wifi

Rete cellulare
E' sicuramente l'approccio più comune per coloro che sono in mobilità. Avrete già intuito che WhatsApp non sia sicura come applicazione. Partendo da quest'assunto (che andremo a sviscerare) possiamo affermare che la sicurezza della trasmissione dati viene demandata interamente alla sicurezza del protocollo di comunicazione utilizzato (gsm, edge, umts, hsdpa).
Intrinsecamente la sicurezza in questa modalità potrebbe essere molto alta, se non fosse che anche il GSM è un protocollo vulnerabile. Qualcuno potrebbe obiettare che la complessità per crackare uno di questi protocolli è alta, a costoro ricordo che un cellulare da 15$ fa miracoli e, per i più smaliziati, lascio anche un paper della Black Hat DC 2011 sul tema.

Rete senza fili
Qui inizia il bello.

Durante questo afoso Agosto 2012, qualcuno ha avuto la bella idea di riscaldare gli animi dello store Android pubblicando un'app in grado di sniffare tutti i messaggi in ingresso ed in uscita dall'applicazione in oggetto. Facile intuire il panico che n'è derivato.
La compagnia s'è affrettata a sistemare con una toppa dichiarando che tutto era stato sistemato... Incredible bullshit! L'applicazione è perfettamente vulnerabile.

Messaggi e nr. di cellulare in chiaro (plain text)
Veniamo all'autenticazione.
Un autentico incubo,

su Android la password è l'MD5 dell'IMEI del dispositivo:
// example IMEI 
$imei = "112222223333334";
// reverse IMEI and calculate md5 hash
$androidWhatsAppPassword = md5(strrev($imei));

su iOS la password è funzione del MAC Address della WLAN:
// example WLAN MAC address 
$wlanMAC = "AA:BB:CC:DD:EE:FF";
// calculate md5 hash using the MAC address twice
$iphoneWhatsAppPassword = md5($wlanMAC.$wlanMAC);

E lo username? E' il vostro numero di cellulare che un attaccante potrebbe già avere o recuperare facilmente (vedi immagine di cui sopra).
Per ottenere l'IMEI si deve avere accesso fisico al device o, meglio ancora, pilotare un'app già presente sul dispositivo, per il mac address basta uno sniffer wifi.

Congratulazioni l'account è servito.

Ecco, ma ora che ci faccio? 
Giusta osservazione, ma c'è una risposta anche per questo.

Qualcuno s'è divertito a fare il reverse engineering del protocollo di comunicazione di whatsapp (disponibile a questo indirizzo) ergo, con un paio di chiamate possiamo anche fare un test di quanto abbiamo ottenuto fino a questo punto
https://r.whatsapp.net/v1/exist.php?cc=$countrycode&in=$phonenumber&udid=$password 
$countrycode = the country calling code 
$phonenumber = the users phone number (without the country calling code) 
$password = see above, for iPhone use md5($wlanMAC.$wlanMAC), for Android use md5(strrev($imei)) 
// Note that the WhatsAPP UDID has nothing to with the Apple UDID - it is something completely different.

Privacy? Quale privacy?

E' addirittura possibile controllare in maniera batch chi ha un account Whatsapp attivo oppure no, ripercorrendo il check iniziale che l'applicazione fa quando si installa la prima volta cioè, interrogare tutta la rubrica indirizzi nel seguente modo:


https://sro.whatsapp.net/client/iphone/iq.php?cd=1&cc=$countrycode&me=$yournumber&u[]=$friend1&u[]=$friend2&u[]=$friend3&u[]=$friend4
$countrycode =  the country calling code
$yournumber = while this SHOULD be your number, it is not required, the API will accept any number 
$friendX = phone number (without the country calling code) from the address book that will be checked, u[] is an array so it is possible to check multiple numbers with one request.


Il servizio risponderà con un semplice file XML con i seguenti elementi:

  • Key P è il numero di telefono del contatto, 
  • Key T è l'uptime (forse), 
  • Key S è lo status. 
  • Key JID è lo JabberID

Per concludere. Io le mie precauzioni le prenderò e voi?