Purposefully Insecure and Vulnerable Android Application (PIVAA) : Part 3

Hacktivities
8 min readJun 17, 2020

--

This article is part 3 in a series that will cover some of the different vulnerabilities present in the “Purposefully Insecure and Vulnerable Android Application” (PIVAA).

Introduction

For Part 3, I will be looking at the following vulnerabilities.

  • Hard-coded Data
  • Enabled Debug Mode
  • Exported Broadcast Receivers
  • Exported Services

Hard-coded Data

The PIVAA application contains sensitive hard-coded data.

  • Vulnerability: Sensitive data hard-coded into an applications code can be easily retrieved by malicious users and used to perform other attacks.

In part 2 of this series, I mentioned that PIVAA used hard-coded encryption keys which is an example of this type of vulnerability. Another example of sensitive data being hard-coded can be seen in the “Configuration.java” file, where credentials have been hard-coded.

Hard-coded Credentials

The following is a list of examples for hard-coded sensitive data:

  • Hard-coded user authentication information (credentials, PINs, etc.)
  • Hard-coded cryptographic keys.
  • Hard-coded keys used for encrypted databases.
  • Hard-coded API keys/private
  • Hard-coded keys that have been encoded or encrypted (e.g. base64 encoded, XOR encrypted, etc.).
  • Hard-coded server IP addresses.

This is not a finite list but it is important to establish what data is sensitive in nature and consider how it could be used by a malicious attacker if discovered.

Recommendations:

  • Store sensitive data in a external file located in a secure directory from where it can be retrieved.
  • Use the Android KeyStore to securely store cryptographic keys.

Enabled Debug Mode

The PIVAA application has debug mode enabled.

  • Vulnerability: Debug mode should be disabled in production build applications because it can expose technical information and facilitate reverse engineering.

I can check if an application is debuggable by examining the AndroidManifest.xml file and determine whether the “android:debuggable” attribute has been set to true.

Debug Mode Enabled in AndroidManifest.xml File

If the application is debuggable as shown above, then it becomes trivial to execute application commands with ADB. I can start a shell on my emulator and gain an interactive shell by using the “run-as” command. From there, I can view the contents of the packages directory where normally I would not have permission.

“run-as” command

I can also use “run-as” to retrieve files that would normally be stored securely in the applications data directory.

Retrieve file using “run-as”

Another approach is to use a tool called “jdp” (Java Debugger) to debug the application and discover interesting information. I can start by running “adb jdwp” to observe what listening ports are active on the emulator.

Ports Listening on Emulator

I can now run the target application and repeat the previous command to see what port it is using.

Port target application is listening on

Next, I can create a communication channel with ADB between the application port and my workstation.

Create Communication Channel

Finally, Using “jdb”, I can attach the debugger to the target application.

Attach Debugger to Target Application

I can view what classes and methods are in the application by using the “classes” and “methods” commands. Since I have already reverse engineered the PIVAA application, I know the names of some interesting classes such as the “com.htbridge.pivaa.MainActivity” class, which acts as a login page. I can list the methods in this class using the “methods” command in “jdb”.

Methods in MainActivity class

I can use “jdb” to setup a breakpoint at this method and control the execution of the app by using the “stop in” command as seen below.

Creating Breakpoint in “jdb”

To hit the breakpoint, I will need to use the MainActivity to attempt a login. Once I attempt to login and the “attemptLogin” method is called, the breakpoint will be hit.

Breakpoint Hit

From here, I will be able to control and see the sensitive values, method arguments, etc. using various commands. For example, I can use the “next” command to execute the next line of code and the “locals” command to see any local variables at a certain point in the codes execution. In this scenario, I was able to see the local variables that contained the login credentials.

Local Variables contain Credentials

Recommendations:

  • For Android applications, make sure the “android:debuggable” attribute is set to false in the AndroidManifest.xml file to disable debug mode.

Exported Broadcast Receivers

The PIVAA application has exported a broadcast receiver without any permissions set. Broadcast receivers are designed to listen to system wide events called broadcasts (e.g. network activity, application updates, etc.) and then trigger something if the broadcast message matches the current parameters inside the Broadcast Receiver.

  • Vulnerability: Any application, including malicious ones, can send an intent to this broadcast receiver causing it to be triggered without any restrictions.

It’s important to identify what this broadcast receiver does by looking at the source code. The PIVAA application allows me to send a broadcast using the “BroadcastRecieverActivity.java” file. This code starts by retrieving a HTML file called “broadcast.html” from external storage.

Broadcast HTML file

The source code then creates an intent and sets the action to “service.vulnerable.vulnerableservice.Log”. This action will be received by the PIVAA application and trigger the execution of some code. The source code also adds extra data to the intent using the “putExtra()” method, which includes the location of the “Broadcast.html” file and data provided by the user. The “sendBroadcast()” method is then used to Broadcast the given intent to all interested broadcast receivers.

Create Intent

Looking at the AndroidManifest.xml file, I can see that the intent filter used by the broadcast receiver matches the action set by the source code used in the “BroadcastRecieverActivity.java” file when creating the intent. I can also see that “VulnerableReciver.java” is the name of the file that implements the broadcast receiver.

AndroidManifest.xml Receiver Element

I moved on to look at the “VulnerableReciver.java” file and identified a class called “onRecieve()” that handles all the broadcasts that are sent to the application. This class takes both of the parameters added to the intent when it was being created in the “BroadcastRecieverActivity.java” file and writes the data input to the file specified by the location input (i.e. “Broadcast.html”).

“VulnerableReciever.java”

I can use Drozer to exploit this exported broadcast receiver. I start by confirming what I have learned so far by using Drozer to identify more information about the exported broadcast receiver.

Broadcast Receiver Enumeration using Drozer

As we can see, the broadcast receiver is exported with no permissions, which means I can create an intent to trigger the broadcast receiver using Drozer. I know from reversing engineering the source code, that the receiver will be triggered by the action “service.vulnerable.vulnerableservice.Log” and will take two parameters which include the data provided by the user and the location of the file that the data will be written to (i.e. “broadcast.html”).

Trigger Broadcast Receiver with Drozer

The command above succeeded in tampering with the “broadcast.html” file which is proven by observing the word “Hacked” as seen in the figure below.

Successfully Tampered with the “broadcast.html” File

Recommendations:

  • Control what applications can receive a broadcast sent from your application by passing a permission alongside the intent when attempting to trigger a broadcast receiver. Only applications that have requested and been granted that permission can receive the broadcast intent from the sending application.
  • Control what broadcasts can be received by your application by setting a permission in the AndroidManifest.xml file which restricts access to a broadcast receiver to only those apps that have requested and been granted that permission.

Exported Service

The PIVAA application has exported a service that performs audio recording and stops after the file reaches 1MB in size. Services are an Android component that runs in the background and does not normally provide a user interface to interact with. These services are used to perform tasks in the background such as downloading large files or playing music, without blocking the user interface.

  • Vulnerability: This service is exported without any permissions in the AndroidManifest.xml file, which means any application can abuse this feature to record audio.

Looking at the AndroidManifest.xml file, I can see the exported service and the “VulnerableService” java file that handles the applications services.

Exported Service

A quick analysis of the code shows that I can simply start the service without needing to provide any added input. This component can be exploited as seen with the broadcast receiver above by using Drozer to create an intent to start the exported service.

Exploit Exported Service with Drozer

This will start the service and cause the application to start recording audio, which will then be stored as a file in root of the external directory as outlined by the application.

Recommendations:

  • Determine if a service needs to be exported.
  • A service is generally not exported but if it is, then strong permissions should be set in the AndroidManifest.xml file.
  • Keep in mind that specifying intent filters with a component in the AndroidManifest.xml file will result in the component being exported by default unless the export attribute is set to false.

--

--

Hacktivities
Hacktivities

Written by Hacktivities

Interested in all things Cyber Security and Technology.

No responses yet