Vulnerability VKontakte: send a message with the page recovery code to someone else's number
On a typical spring day, doing “preparation” for the Unified State Exam on computer science, I came across an article about the vulnerability of Facebook , which allowed hacking all accounts on a social network, for which they paid $ 15,000. The essence of the vulnerability was to search for recovery codes on the company's test domain. I thought, why is VKontakte worse? And I decided to try to do a similar trick with them. Knowing that the web version is already quite well researched, the victim should have become an Android client, and what came of it can be read under the cut.
Look traffic
First of all, I wanted to find out what information the application transmits to the network during the page recovery process. Fiddler acted as an assistant in this matter, I configured it and the Android device as written in the official documentation . Thus, all HTTP / HTTPS requests from the device become available in Fiddler. Now, in the app, feel free to exit from your VKontakte account and click on the “Forgot your password?” Button. After entering the phone number, the application sends 2 HTTPS requests. Of particular value is the second, because it is he who is responsible for sending SMS with a recovery code. ')
Special attention should be paid to some query parameters:
phone - the number to which the SMS is sent session_id - randomly generated session of the restore operation
Attempting to send a request by changing it did not succeed. The “signature” parameter, which acts as a “signature”, interferes, as it is generated we will understand a little later.
For the subsequent analysis, in the application, we will enter a random recovery code and continue to monitor network activity. We see the following request, it checks the correctness of the entered code. Since the code was random, the check failed.
Honestly at this point, I wanted to start sorting through recovery codes, changing the value of the “code” parameter. Unfortunately, this request is also protected from being modified using "signature". We'll have to figure out how this signature is generated.
Reverse engineering: decompilation
For the initial analysis, you can try to decompile the VKontakte application. So you can get some parts of the source code in Java.
How to do it
1. Download and unzip dex2jar and jd-gui 2. Open apk applications as a regular archive and drag and drop .dex files to d2j-dex2jar.bat
We open in jd-gui all received .jar files. And without hesitation, we do a search for the string "signature".
The libverify library under the authorship of Mail.Ru clearly falls out of the general list of those found. We look and we are not mistaken, the generated string is very similar to the url from previous requests.
This library is made in the best traditions of security through obscurity, all code is securely obfuscated. Therefore, through jd-gui, I managed to find out only that the “signature” hides the MD5-hash from the unknown line.
Reverse Engineering: Disassembling
I needed to find out what line goes to ru.mail.libverify.utils.mb (). The easiest way to do this is to change the application code slightly. Well, let's try. First we use apktool , with the command:
apktool.jar d vk.apk -r ( -r )
Now, in the folders with the smali-code, we find the file in which the MD5 is generated. In my case, the path was as follows: smali_classes3 \ ru \ mail \ libverify \ utils \ m.smali. Go to the desired method:
The string you wanted to know was passed to the function in the first register parameter (p0). Therefore, to get it, you should output the parameter somewhere, for example, in Logcat. Add a few lines to the code:
After that, after removing the original application, you can install and run our modified client VKontakte. To get the logcat from the device, we will use the Android Debug Bridge . We connect the Android device via USB and execute the following commands in sequence:
adb devices adb logcat
As soon as they joined the device and got the opportunity to watch the logs, click again on "Forgot your password?" And enter the phone number. The following entry appears in the adb window:
It becomes clear that the hash string consists of successively glued: part of the url, query parameters and another hash string (506e786f377863526a7558536c644968). And now, knowing the generation algorithm “signature”, we can start sending our “signed” requests.
Study
For research, I wrote a simple C # program that sent a request to send an SMS and tried to enter a code. Using it, I entered random recovery codes. But expectedly rested on the limit attempts:
I tried to resend SMS, in the hope that the limit would disappear after that. To my regret, the message arrived, but I still could not enter the code:
I decided to send requests with different session_id, sms came with other recovery codes, but I still rested against the limit, now not in “ATTEMPTLIMIT”, but in “RATELIMIT”.
About bruteforce
Watching incoming SMS, I noticed some common feature codes. The recovery code consisted of 4 digits (at the time of writing, they increased yes to 6) and the same numbers were not next to each other. That is only ~ 6500 possible codes. I thought it was quite possible in 5 attempts to guess the code, for example, they did it on Facebook . But then still postponed this venture.
I tried to bypass the limits in all possible ways. I changed the IP addresses, request parameters, phone numbers, but I could not make more than 5 attempts to enter the code.
And here, almost by accident, I decided to send the recovery code to two different numbers, but using the same session_id. To my surprise, there was no chapel when I saw the same SMS on both phones. Here's how it worked:
Because of the proxy, additional verification is required.
Thus, the attack was obtained:
We send a request to send SMS to subscriber A with session_id C, he receives the code 1234
We send a request to send SMS to subscriber B with session_id C, he receives the code 1234
Now, if subscriber A knows the telephone number of subscriber B, he can restore his page. It was possible to restore only that page, to the number of which the last SMS came with a similar session_id.
Conclusion
Immediately after the discovery of the vulnerability, I wrote a report on HackerOne. After 17 hours, the vulnerability was eliminated. A few days later I was paid $ 2000. This vulnerability allowed hacking most of the accounts in the social network, only accounts with two-factor authentication were safe (they cannot be restored by phone number). Report
PS Unified State Exam in computer science passed by 97 points. Unfortunately, the remaining items are not so successful.
UPD: The libverify library was also used in ICQ, hence the vulnerability existed there. In the bug-bounty ICQ program, I was paid an extra $ 1000. Report