Alright, today I thought would get technical! Let’s talk about a recent mobile application assessment we performed here at Packet Ninjas. During this assessment, we had to bypass some controls that the application put in place to be able validate our test device. This one may get a little… Errr a lot technical so try to hang in there until the end. Here we go.
For today, we will be focusing on an Android application. Most Android applications are just a front end that interacts with a backend JSON API. This means a mobile application assessment is very similar to an API assessment. The first thing that needs to be configured is a proxy to intercept the traffic between the mobile device and the server. This allows us testers to view the traffic and begin analyzing this traffic for flaws and vulnerabilities. For most modern applications this is easily performed by using Frida and Objection.
These frameworks work together to enable Ninjas to reverse engineer the application. Through this, we can inject custom scripts to go further in the testing process.
So first objective- Bypass the SSL Certificate Pinning in the Android application. Most modern Android applications utilize this protection.
SSL Certificate Pinning is the process of associating a host with its certificate. In other words, the application is configured to reject all but one predefined certificate included in the application bundle. This means when you intercept traffic with a proxy like Burpsuite, the server will see the SSL certificate of the proxy (Burpsuite) and reject the traffic.
Good thing objection has some predefined commands to accomplish this for us. The capture below is the command to start the application on our mobile device with sslpinning disabled. This allows us to view the traffic in a proxy like Burpsuite and the client/server will accept it.
For most applications this is all that is needed. However, the application we were testing has a custom validation mechanism that required more information.
Basically, additional information was being sent during the validation process. Using Burpsuite we can see the traffic that is coming and going. However, the validation process in the mobile app was failing but why? Aha, Watson! We must investigate further. Luckily for us, Frida and Objection can dynamically analyze the application in real time as we make each requests.
So, let’s get into it.
First, let’s decompile the Android apk file using jadx. This will decompile the application into java and let us search through classes and methods. Using jadx, we will attempt to find what the validation request is doing and if we can bypass it.
After a lot of digging and searching through key words like “Validate”, we found a method called “validateDevice”. This method seems to require a few things like a Context, a JSONObject, and a VolleyError. After review, I think we can bypass this method if we pass it the correct information. Below shows how it looks in jadx.
Using this information, let’s dynamically analyze the application to see what is going on in real time using objection.
From the below screenshot we can see that the method is being called but it isn’t returning anything. It would be super easy if this was returning a true or false, but we aren’t that lucky. Looking closer, we can see something being called in the backtrace is validating the device.
More code review along with the above backtrace reveals that “splash.ActivitySplashScreen$onValidationRequired$1.invoke” is the correct method we need.
This method looks like the below screenshot in jadx. Notice jadx renamed it to invoke2 to avoid a collision. This made it extra hard to find. I was never very good at the old “Seek & Finds”. Unfortunately that still remains true today so it took me longer to find this than it should have.
Let’s capture this method in Objection and see what it is doing.
Volley (a network request library) is throwing a network error. Researching more on Android Volley and reading through the code, I realized that the application’s validate function is using a custom implementation of Volley, and because of the customization, the objection SSL Pinning Bypass methods are not working for it.
Fortunately for us, this Volley method is only being used for the Validation method….so let’s break the rules and bypass it instead of bypassing a custom implementation of Volley entirely.
But how? By utilizing Frida and a custom script of course. So, we need to hook our identified method and overload it.
The above code hooks our class “splash.ActivitySplashScreen$onValidationRequired$1” and overloads it allowing us to access what is inside whenever it’s called.
Next, lets pass it some variables and call it.
It took me way too long to figure out how to call this using Frida… But YAY for terrible documentation. Eventually I found an article that was calling other android methods using Frida that finally revealed how to do this … And it’s actually pretty simple.
This will call the method and pass it a string to be returned as a JSONObject.
Now, what JSONObject are we passing?
Using burpsuite and all its magical glory, we captured a valid response from the validate request that the mobile app was sending and entered that as our string.
This leaves us with the following.
So, lets run this script and see what we get.
BOOOM!!!! Success, we can now log in.
So yeah, a LOT of JSONs, lots of methods, apps, words… But now that this is complete, we can start our assessment of the application.
Hopefully I was clear and demonstrated the step by step process we took to get there. I hope you learned something. I know I did after such a deep dive through Frida and Objection.
Until next time.