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.
- InsecureBankv2 installed on Android device or emulator
- Drozer agent installed on Android device or emulator
- Drozer console runs and connected to drozer agent
- Bytecode Viewer installed on a host machine
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
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
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:
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
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:  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
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.
In this post we looked at exploiting unsecured broadcast receivers. We also made several changes to protect broadcast receiver with custom permission.