Vulnerable Android Broadcast Receivers
This article is part of the series of blog posts about Android application security. In this series we try to learn Android application security by looking at one particular vulnerable application, identify vulnerabilities, and show how to fix them.
Prerequisites
- InsecureBankv2 installed on Android device or emulator
- Drozer agent installed on Android device or emulator
- Drozer console runs and connected to drozer agent
Optional:
- Bytecode Viewer installed on a host machine
Getting information
In the previous post we analyzed exported Activities. In this post we will look at exported Broadcast Receiver. Let’s use drozer to check which receivers we have in our application:
dz> run app.broadcast.info -a com.android.insecurebankv2 -i
Package: com.android.insecurebankv2
com.android.insecurebankv2.MyBroadCastReceiver
Intent Filter:
Actions:
- theBroadcast
Permission: null
As you see, MyBroadCastReceiver
processes actions with name theBroadcast
, it is exported and not protected by a permission, meaning that any app can create an Intent
which will result in this receiver being triggered. In order to determine what this receiver can do, we need to look at the source code. There are different ways how to do that, I will use Bytecode Viewer which is handy because it contains multiple decompilers and allows to compare output that they produce side-by-side. On the image below you can see how the source code looks like:
If we look into the source code, we would see that two parameters are being retrieved from the Intent
:
String str1 = paramIntent.getStringExtra("phonenumber");
String str2 = paramIntent.getStringExtra("newpass");
Then, the code reads data stored in Shared Preferences, does some cryptographic operations, and at the end calls SmsManager.sendTextMessage()
.
Exploit
Let’s issue a drozer command to try to trigger our Broadcast Receiver:
dz> run app.broadcast.send --action theBroadcast --extra string phonenumber 12345 --extra string newpass A1!B2!C3!
If we look at our Android device now, we will see that we are about to send an sms message. Setting a premium rate sms number and forcing users to send messages without their consent is one of the ways bad guys can be making money:
Fix
Obviously, the need to export Broadcast receiver in this case is probably negligible. However, imagine that you do have a need to export it. A naive approach one might take is to introduce a custom permission and protect your receiver by this permission. Below are the changes that one would need to introduce to AndroidManifest.xml
:
After these changes, if we try to trigger an action on MyBroadCastReceiver
using drozer, the following error may be observed in logcat:
.
Unfortunately, the above approach does not help much. The only thing that is required from an attacker to be able to execute this action is to add the following string to his application’s manifest:
<uses-permission android:name="com.android.insecurebankv2.MyBroadCastReceiverPermission" />
There are many users out there who can be tricked into installing applications that request more permissions than they actually need. If you are using drozer, you may even rebuild agent apk with any permission by issuing the following command:
drozer agent build -p com.android.insecurebankv2.MyBroadCastReceiverPermission
If we reinstall agent on the Android device and try to get information about it using drozer, you will see the following:
dz> run app.package.info -a com.mwr.dz
Package: com.mwr.dz
Application Label: drozer Agent
Process Name: com.mwr.dz
Version: 2.3.3
Data Directory: /data/data/com.mwr.dz
APK Path: /data/app/com.mwr.dz-1.apk
UID: 10131
GID: [3003]
Shared Libraries: null
Shared User ID: null
Uses Permissions:
- android.permission.INTERNET
- com.android.insecurebankv2.MyBroadCastReceiverPermission
Defines Permissions:
- None
We can now successfully execute an action of broadcast receiver. If you observe logcat, you will see the following:
Note: As you see on the above image, the information that application logs is quite extensive and includes both an old and new passwords. Prior to Android version 4.1, third-party applications could request android.permission.READ_LOGS
and use information available in the log. As of now, only system applications can use this permission.
So, what would be the better way to protect our broadcast receiver? Well, if we are sure that we want this action to be triggered out of applications that we control, we can use signature level permission. In this case, only applications that we signed with the same key will be able to obtain this permission. Here are the changes that we have to introduce to AndroidManifest.xml
:
After making the changes and reinstalling InsecureBank application on the device, try to trigger an action on our broadcast receiver will result in permission denial.
Summary
In this post we looked at exploiting unsecured broadcast receivers. We also made several changes to protect broadcast receiver with custom permission.