Whatsapp what's inside?

In this article, we will take a detailed look at how you can study the protocol of the messenger, answer the question “Can WhatsApp read our correspondence?” And attach all the necessary code in PHP.
general information
WhatsApp uses a modified version of the XMPP protocol as a message format. All messages are compressed by replacing frequently used words with 1 or 2 byte tokens (for example, instead of “message” - write byte 0x5f), this results in what is called FunXMPP.
Some packages may be optionally zlib compressed. The received packet is encrypted with AES GCM 256-bit and transmitted to the server.
To obtain encryption keys, the client performs noise protocol handshake. Here it is well described . For some reason, all developers of open implementations refused to implement it in the code and hung up the “end of support” die, we will fix it.
At the first connection, a full handshake is performed. After a successful connection to the server, each time a new key is issued for the next session, with the help of which later a connection is made without exchanging keys.
WhatsApp supports end-to-end encryption using libaxolotl (Signal Protocol), two versions are implemented in the code - at first they just did encryption, and then added the alignment and called it v2. There is only one problem - because it is a centralized system, then the key transfer goes through the WhatsApp server, so purely technically there are no obstacles for the messenger developers to transmit false encryption keys and fully read the correspondence. But this has no retroactive effect - reading messages in hindsight will not work.
By the way, when you receive a message from an unauthorized contact, the "complain about spam" button is displayed in the messenger, by clicking on it we will not only block the contact, but also forward the message text via a secure channel (already open!). Without studying the application code entirely, there is no way to guarantee that this functionality is not used in any other cases.
To verify the authenticity of the encryption keys in the WhatsApp application, you can go to the contact card, select the "Encryption" item, after which the application will offer to scan a QR code on the recipient’s device. Thus, by the way, you can make a custom application based on the WhatsApp protocol that will constantly monitor the status of encryption keys and issue beautiful dice “NSA is watching you” or “You are safe”: given the variety of instant messengers, replace one of them with this The application will even be useful.
The operation algorithm can be assumed as follows: a device that displays a QR code encodes its public key into it, a device that reads a QR code compares the key with the one available in its database. This is a safe way to verify the key, but only if there are no bookmarks in the application.
When sending multimedia files are uploaded to the WhatsApp server, we did not conduct additional studies whether they are encrypted there. Most likely they are not encrypted, as the application developer trusts himself, and the link to the file is transmitted through a channel protected by end-to-end encryption.
Account registration
Registration takes place in three https requests for the v.whatsapp.net domain (they can be spied in any known way, for example burp or mitmproxy, the application uses certificate pinning, which bypasses using ssl kill switch).
v.whatsapp.net/v2/exists?cc=код_страны&in=телефон&id=id_устройства&lg=en&lc=zz
It doesn’t do anything useful, it used to be used to check if this number was already registered (most likely until someone started sorting through their database)
v.whatsapp.net/v2/code?method=sms&cc=код_страны&in=телефон&token=токен&sim_mcc=mcc&sim_mnc=mnc&id=id_устройства&lg=en&lc=zz&параметры_сквозного_шифрования
Actually it asks for the activation sms code. A similar request can also be used to receive a call. End-to-end encryption settings are optional - they can be configured upon further connection. The token turns out like this:
md5 ("0a1mLfGUIBVrMKF1RdvLI5lkRBvof6vn0fD2QRSM". md5 ("21752"). "phone")
The first line is the encrypted string landscape, whatever that means. You can substitute any version of the application (21752) (the most curious can try to register with a version that has not yet been released); in the application code, the hash from the version is ready-made, but something similar to the md5 hash is quickly selected.
v.whatsapp.net/v2/register?cc=код_страны&in=телефон&code=код_из_смс&id=id_устройства&lg=en&lc=zz
This request, respectively, confirms the registration with the code received by SMS or call.
In requests is used
User-Agent: WhatsApp/2.17.52 iPhone_OS/7.1.2 Device/iPhone_4
. The correct agent is most likely required to correctly verify the token.MITM
All this is not known the first day - there are several implementations of the WA16 protocol (Chat-API, Yowsup), from the current WA20 the difference is essentially only in the Noise Protocol. With this information, we can develop a local MITM to view decrypted application traffic. Because Initially, the XMPP application protocol - everything that happens there will be understandable immediately from the decrypted traffic, so there is no special need to dive into the jungle of the disassembler.
To launch MITM, we will introduce ourselves as a real WhatsApp server, perform a full handshake, after which our application will listen for traffic redirecting it to the original whatsapp server and vice versa. To do this, we need to change the original application:
All operations are carried out in the following configuration: iPhone 4, iOS 7.1.2, IDA 7, WhatsApp 2.17.52.
Patch application
1. We will perform a full handshake at every connection, this will greatly simplify our lives. In the method,
-[NoiseHandshakeManager initWithLoginPayload:clientStaticKeyPair:serverStaticPublicKey:]
if present, serverStaticPublicKey
is executed ResumeHandshake
, and if not FullHandshake
. 

The serverStaticPublicKey is stored in the register R0, and in its absence, the transition to FullHandshake is performed. And we will make this transition unconditional. To do this, replace two bytes

with

Result.

In the decompiler, we see that one of the condition branches has become unreachable and is not displayed.

2. We will disable server signature verification, as we do not have the private keys of the original server. Without this change, it will be impossible to listen to traffic. To do this, make changes to the (bool) - method
[NoiseHandshakeManager validateNoiseCertificate:serverHandshakeStaticPublicKey:]
.
We need the function to always return one. Now the result of the certificate verification from the register R6 is placed in R0.

Let's make the unit write in R0.

As a result, we get the

Application compiled with all the debugging information, so we additionally need to rename, describe the structures and generally perform the reverse process - when creating the patch, it is actually not required. Images are shown immediately after the decompiler is launched, without additional processing.
iOS 7.1.2 does not verify the authenticity of application binary files, so all changes can be made directly in the application file. In later versions of iOS, you can make the same changes in the memory of the running application.
Writing a code ...
Next, with the help of the IDA and long painstaking efforts, we prepare the code that successfully runs NoiseHandshake on WhatsApp servers. Then we implement a fake server - we do all the same encryption operations, but in the reverse order (it sounds simple, but if you don't do it every day - it's still a headache). Ready code is here .
Download the MITM application obtained from the link above to your computer. Install PHP 5.6 (another version will work, this version was used in my configuration). Two more libraries will also be needed:
- first
- second
Intercept connection
It remains only to make the application connect to our server, instead of the present. The application connects to one of the servers e% d.whatsapp.net (where% d is a number from 1 to 16, for example e5.whatsapp.net), each of which resolves to several IP addresses, each time - different, in total more than 300 servers. The easiest way is to replace the server’s DNS answer and forward it to our computer with MITM.
To do this, put the phone and the computer on the same network (literally any wifi router will do), put the DNS on the phone to our computer on which we install bind9 with the following host:
$ TTL 86400 @ IN SOA ns.whatsapp.net. admin.whatsapp.net. ( 2017100500 28800 7200 1209600 86400) @ IN NS @ @ IN A YOUR IP v IN A 184.173.136.86 v IN A 174.37.243.85 * IN CNAME @
Watching traffic
Next, edit mitm.php - you need to substitute your phone number in the username field and the contents of the cck.dat file (located in the application directory) in the password field.
Run php mitm.php. We launch the WhatsApp application and see the following picture:

In the screenshot you can see two packages from the server - a message about successful authorization and some settings. Thus, absolutely all application traffic looks like this - everything is readable and additionally disassembling the application, in most cases, is not required.
An algorithm for turning FunXMPP into readable text is available in all WhatsApp libraries. Inside the simplest state machine, I will not additionally paint it here.
conclusions
The application is made with high quality, uses modern encryption protocols, but deep down lies the XMPP left over from the originally used ejabberd. Using protobuf, judging by the current vector of application development, would be more logical, but the historical legacy is too expensive.
The service suffered for a long time from mass mailings - the code of open projects contributed widely to this. At the moment, no newsletters have been received for a long time - the developers introduced a limit on the number of messages sent to unauthorized contacts. It is this add-on (technically implemented entirely on the server side), in my opinion, that has decisively put an end to the confrontation between mailing list lovers and anti-mailing list employees (if they have one).
Purely technically, there is nothing complicated in such an algorithm, for developers of other messengers (hello, Viber, I receive spam at least once a month), it’s worth taking a note of this technique.
Thanks for reading, I hope to read about it was as fun and interesting as conducting the study.