2

How to exploit a debuggable Android application.

A debuggable Android application could allow an attacker to access to sensitive information, control the application flow and even gain code execution in the context of the debugged application. For this we will be using several tool, but we will be focusing on the Java Debug Wire Protocol (jdwp) through the Android Debug Bridge along with The Java Debugger (jdb).


Debugging plays a key role in understanding specific conditions of the code been executed, how each line of code behaves and, if necessary, what needs to be done to fix a specific error. This is certainly useful while the application is in the development phase, however, once the application is in production, allowing the application to be debuggable may represent a security risk.

With the apk of the application you want to test at hand, you can use apktool to obtain a readable version of the AndroidManifest.xml configuration file. Here you should look for android:debuggable flag, if it’s set to true, debugging is available, otherwise if set to false. Here we can see that the target application, in fact, has this flag set to true:

Here, we will be using the Java Debug Wire Protocol (jdwp), according to the Oracle documents, jdwp is the protocol used for communication between a debugger and the Java Virtual Machine which it debugs, jdwp allows the debugger to either work in a different process in the same computer or on a remote computer. [1] For Android-based applications, the Android Debug Bridge (adb) provides the jdwd command, which lists the PIDs of processes hosting a JDWP transport. In order to find the PID of our application, we first need to run the adb jdwp command, start the application afterwards and run the command again, to see what PID was added to the list.

First we run the adb jdwp command to get the first list of PIDs running in our Android Virtual Device (avd):

On the avd, we install and run the application we want to debug, in this case we will be using a small, simple, Android application we have created for this purpose:

Once the application is running, we run the adb jdwp command again and see what new PID is added to the list we got on the first step:

In this case, we notice that the new PID in the list is 3149 and thus this is the PID of the application we want to debug. Now, we need to setup a port listener on our workstation and forward it’s traffic to the PID of our application, for this we use the adb forward command:

We can check that the port listener is up and running by issuing the netstat command:

Now we proceed to attach The Java Debugger (jdb) to the port listener running on our workstation, in this case running on port 7777. By doing this, and through the adb forward done previously, we can attach the debugger to the PID of our Android application:

You should get a command line like the shown in the image above. Here, we first list the classes like below:

We scroll down until we find the class names for our application:

We choose which class we want to inspect and use the methods command to get a list of available methods:

We choose which method we want to debug and setup a breakpoint by using the stop in command, in this case we will be debugging the attemptLogin() method:

Once the breakpoint is set, we proceed to our Android application, fill the login form and hit the Sign In or Register button:

We go back to our debugger and notice that the breakpoint was hit and we now get a main[1] prefix in our console:

Once here, you can use the locals command to show what variables (if any) are available at this code line. Below we can see no variables are shown in this attempt, so, we use the next command to move to the next line:

Until we find some interesting information, email and password in this case:

From here, you can control the application flow by changing variable values or gaining code execution with a code similar to this:

[1]https://docs.oracle.com/javase/7/docs/technotes/guides/jpda/jdwp-spec.html


Conclusion

While developing an application, a debugger is your ally and best friend, however, once your application has been shipped, allowing your Android application to be debuggable may leave it open to exploit. If you want to mitigate this risk, make sure your application is not debuggable when shipped, you can do this by setting the android:debuggable flag to false or by letting Android Studio assign it automatically depending on the selected build.