Penetration testing on mobile applications – The hard way

In this period, I spend a huge portion of my working time doing penetration test on mobile applications, mainly Android and iOS. I personally consider this kind of test much more difficult than the penetration testing of web applications. Is it true? It depends on what you mean for “mobile penetration testing”.

As an example, I will talk of a penetration test that I have recently executed on an iOS mobile application (this article will be less technical than usual, because I can’t obviously publish details on my customer’s applications).

Let’s begin the test.

The application checks for jailbroken devices? Yes/no. The application implements certificate pinning? Yes/no. The application backups critical data? Yes/no. The application saves critical information in clear text? Yes/no. The application logs critical data? Yes/no. And so forth and so on.

Up to here, there is nothing difficult, right? (In reality, this is not true in all the cases, but for this example we will pretend it is true).

Good, let’s begin to test the backend. We start our favorite proxy (obviously Burp Suite, https://portswigger.net/burp/) and we begin to intercept communications. Uhm, damn. The communications are encrypted. There are two layers of encryption, the channel (TLS/SSL) and also the POST parameters themselves are encrypted.

And now? Now we can continue the test in two ways. The easy way or the hard way.

The easy way is: “The backend is safe because the parameters are encrypted”. Easy, but definitely not true.

We prefer the hard way. If we break the encryption, maybe we can find juicy backend vulnerabilities, like SQL Injection, local file inclusion or remote command execution.

Now, the difficult part of the job. We have to understand how the mobile application communicates with the server. In Android applications, this phase can be easier. If the application is not highly obfuscated, Java Bytecode can be easily decompiled. But unfortunately we are testing an iOS application. For this phase, we mainly use two tools:

  • Radare 2 (http://rada.re/r/), one of best tools for disassembling the code
  • Frida (http://www.frida.re/), a great dynamic instrumentation framework that works on iOS, on Android and also on Windows!

With Radare 2 we can disassemble application code and reverse it. With Frida we can speed up enormously the process, by analyzing the application at runtime.

After a long and arduous reversing work, we understand that the application encrypted the communications with a combination of both symmetrical and asymmetrical encryption algorithms. Every request was also signed and discarded by the server if the signature is not correct. Objectively, the overall encryption system was great!

Well, now that we understood the encryption system, we have to understand how to test the backend of this application.

As usual, the best way (in my opinion) is develop a custom plugin for Burp Suite. The plugin must decrypt application requests, allow the tester to modify the decrypted request and finally encrypt and sign again the request. In the same way, the plugin must also decrypt server responses. This plugin allows easy penetration testing on the backend (plus a Frida script that dynamically bypassed some troubles caused by asymmetrical encryption system).

Is it necessary all this work? Yes, it is! By protecting the communications with a strong encryption algorithm, the developers may wrongly assume to have protected the backend server and consequently may not implement adequate checks on the server-side functions, in order to block attacks to the system or to the databases. If the penetration tester does not find these issues, a threat agent maybe will find them and exploit them.

What is the point? The point is that a good penetration test on mobile applications requires a lot more skills that a good penetration test on web applications. Reversing skills and developing skills (besides obviously penetration testing skills) are necessary in order to obtain a good result. Consequently, as usual, not all the penetration testing jobs give the same results!