WhatsApp, what's inside?
As a continuation of the research publications of our company on the internal mechanisms of the world's largest messengers. Today we will look at WhatsApp in its current state. In fact, the insides have not changed much over the past three years, the changes there are rather cosmetic.
In this article we will look in detail how to study the protocol of the messenger, answer the question "Can WhatsApp read our correspondence?" And I will attach all the necessary code in PHP.
General InformationAs a message format, WhatsApp uses a modified version of the XMPP protocol. All messages are compressed by replacing frequently used words with 1 or 2 byte tokens (for example, instead of "message" - writing a byte of 0x5f), this results in what is called FunXMPP.
Some packages can be further compressed with zlib. The received packet is encrypted with AES GCM 256-bit and transmitted to the server.
To obtain encryption keys, the client executes a noise protocol. Here is well described. From the embodiment in the code, all developers of open implementations for some reason refused and hung the die "end of support", we will fix it.
At the first connection, a full handshake is performed. After a successful connection to the server, a new key is issued each time for the next session, with which the connection is subsequently made without a key exchange.
WhatsApp supports end-to-end encryption using libaxolotl (Signal Protocol), the code implements two versions - first they just made the encryption, and then added the alignment and called it v2. There is only one problem here. this is a centralized system, then the transfer of keys goes through the server WhatsApp, so there is no technical obstacle for the messenger developers to transfer dummy encryption keys and read the correspondence completely. But this does not have the retroactive effect - it is not possible to read the messages in hindsight.
By the way, when you receive a message from an unauthorized contact - the messenger displays a button to "complain about spam", clicking on it will not only block the contact, but also send it through the secure channel (already in clear!), The text of the message. Without studying the application code entirely, there is no way to ensure that this functionality is not used in any other cases.
To check the authenticity of the encryption keys in the WhatsApp application, you can go to the contact card, select the "Encryption" option, and then the application will offer to scan the QR-code on the recipient's device. Thus, by the way, you can make a custom application based on the WhatsApp protocol, which will constantly monitor the status of encryption keys and give out beautiful dice. "NSA watches you" or "You are safe": taking into account the variety of messengers, replace one with such the app will even be useful.
The algorithm of work can be assumed the following: the device displaying the QR-code encodes its own public key into it, the device that reads the QR-code checks the key with the key in its database. This is a secure way to verify the key, but only if there are no bookmarks in the application.
When sending media files are uploaded to the WhatsApp server, we did not conduct additional research whether they are encrypted there. Most likely not encrypted, because the developer of the application trusts itself, and the link to the file is transmitted over the encrypted encrypted channel.
Registering an accountRegistration takes place in three https requests for the domain v.whatsapp.net (you can peek them in any known way, for example burp or mitmproxy, in the application you use certificate pinning, which is bypassed with ssl kill switch).
v.whatsapp.net/v2/exists?cc=code_instruction&in=phone&id=id_device&lg=en&lc=zzdoes not do anything useful, used to be used to check if this number is already registered (most likely until someone started to sort out their database)
v.whatsapp.net/v2/code?method=sms&cc=code_instruction&in=set phone&token=kitchen&sim_mcc=mcc&sim_mnc=mnc&id=id_device&lg=en&lc=zz&config_secure_coding optionsActually it requests the activation code for sms. You can also use a similar request to receive a call. The parameters of end-to-end encryption are not necessary, they can be configured with further connection. The token is obtained as follows:
md5 ("0a1mLfGUIBVrMKF1RdvLI5lkRBvof6vn0fD2QRSM". md5 ("21752"). "telephone")
The first line is the encrypted line landscape, whatever that means. The version of the application (21752) can be substituted for any (the most curious can try to register yet not released version), in the application code the hash from the version is sewn up ready, but something similar to md5-hash is quickly picked up.
v.whatsapp.net/v2/register?cc=code_country&in=phone&code=cod_sms_id_id_id_device&lg=en&lc=zzThis request, respectively, confirms the registration with the code received by SMS or call.
The queries use
User-Agent: WhatsApp / 2.17.52 iPhone_OS / 7.1.2 Device / iPhone_4. The correct agent is most likely required, for correct verification of the token.
MITMAll this is known not 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 the decrypted application traffic. Because Initially the protocol of the XMPP application - then everything that happens there will be completely understandable immediately from the decrypted traffic, so there is no special need to dive into the jungle of the disassembler.
To run MITM - we will introduce ourselves as a real WhatsApp server, execute a full backend, after which our application will listen for traffic redirecting it to the original server whatsapp and back. To do this, we will need to modify the original application:
All operations are performed in the following configuration: iPhone 4, iOS 7.1.2, IDA 7, WhatsApp 2.17.52.
Patch application1. We will perform a full handshake every time we connect, this will greatly simplify our life. In the
- [NoiseHandshakeManager initWithLoginPayload: clientStaticKeyPair: serverStaticPublicKey:]method, if it is serverStaticPublicKey, executes ResumeHandshake, and if there is no FullHandshake.
In the R0 register, serverStaticPublicKey is stored, and if it is not there is a transition to FullHandshake. And we will make this transition unconditional. To do this, replace the two bytes
In the decompiler we see that one of the condition branches has become unreachable and is not displayed.
2. We will disable the server signature verification, because we do not have private keys of the original server. Without this change, you will not be able to listen to traffic. To do this, we make changes to the method (bool) -
[NoiseHandshakeManager validateNoiseCertificate: serverHandshakeStaticPublicKey:].
We need the function to always return a unit. Now the result of checking the certificate from the register R6 is put in R0.
We make so that in R0 we write a unit
As a result, we obtain
The application is collected with all the debugging information, so in addition to perform renaming, describe the structure and generally perform the process of reversal - when creating a patch is actually not required. Images are shown immediately after the decompiler is started, without additional processing.
iOS 7.1.2 does not verify the authenticity of binary application files, so all changes can be made directly to the application file. In later versions of iOS, you can make the same changes in the memory of the running application.
We write the code ...Then, using IDA and a long, painstaking effort, we prepare the code that successfully implements NoiseHandshake on WhatsApp servers. Then we implement the fake server - we do all the same encryption operations, but in the reverse order (it sounds simple, but if you do not do it every day - that's another headache). The finished code is here .
Download the MITM application from the link above. Installing PHP 5.6 (another version will work, in my configuration this version was used). You will also need two more libraries:
Intercepting the connectionIt remains only to force the application to connect to our server, instead of the present one. 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 is divided into several IP-addresses, each time - different, in total more than 300 servers. The easiest way is to replace the DNS response of the server and send it to our computer with MITM.
To do this, we put the phone and the computer in one network (literally any wifi router will work), on the phone we put DNS on our computer on which we set bind9 with the following host:
@ IN SOA ns.whatsapp.net. admin.whatsapp.net. (
@ IN NS @
@ IN A YOUR_AIPI
v IN A 188.8.131.52
v IN A 184.108.40.206
* IN CNAME @
We are watching trafficNext, edit mitm.php - you need to substitute your phone number in the username field and the contents of the file cck.dat (located in the directory with the application) in the password field.
Run php mitm.php. Run the WhatsApp application and see the following image:
The screenshot shows two packages from the server - a message about successful authorization and some settings. Thus, it looks absolutely all the traffic of the application - everything is readable and the application is not disassembled, in most cases, it is not required.
The algorithm for converting FunXMPP into readable text is in all the libraries with WhatsApp. Inside the simplest state machine, I will not paint it here.
ConclusionThe application is made high-quality, uses modern encryption protocols, but deep inside lies the XMPP remaining from the originally used ejabberd. Judging by the current development vector of the application, it would be more logical to use protobuf, but the historical legacy is too expensive.
Service for a long time suffered a lot from mass mailings, - the code of open projects widely contributed to this. At the moment, no mailings have come for a long time, - the developers have imposed a limit on the number of messages sent to unauthorized contacts. It is this addition (which is technically implemented entirely on the server side), in my opinion, decisively put an end to the opposition of mailing fans and employees of the anti-mailing department (if they have one).
Purely technically there is nothing complicated in this algorithm, the developers of other messengers (hello, Viber, - get spam at least once a month) - it's worth taking this note for a note.
Thanks for reading, I hope to read about it was as fun and interesting as doing research.
|Vote for this post
Bring it to the Main Page