In this post, I will provide an in-depth technical analysis of the malicious Android application known as “Free Followers,” specifically focusing on its ransomware functionality.
APK Metadata
Malware sample
: Malware bazaar
MD5
: 2ddbc785cd696041c5b0c3bd1a8af552
SHA256
: 5251a356421340a45c8dc6d431ef8a8cbca4078a0305a87f4fbd552e9fc0793e
SHA1
: 1269636a5197ee7a1402e406c91177bf6a149652
File Size
: 2.7 MB
CRC32
: 7cd1fa65
Package Name
: com.XPhantom.id
Android Manifest
We can recover the manifest by extracting and decoding the contents of the apk using apktool.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="23" android:compileSdkVersionCodename="6.0-2438415" android:installLocation="internalOnly" package="com.XPhantom.id" platformBuildVersionCode="23" platformBuildVersionName="6.0-2438415">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<application android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
<activity android:label="@string/app_name" android:name="com.XPhantom.id.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.INFO"/>
</intent-filter>
</activity>
<service android:enabled="true" android:name="com.XPhantom.id.MyService"/>
<receiver android:enabled="true" android:name="com.XPhantom.id.BootReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
</application>
</manifest>
The manifest says that there’s one activity, one service and one receiver. Apart from that, the required permissions seem to be too much for a free followers
application. Let’s decompile the apk using JADX.
It starts a service using
startService()
as soon as the application is run. A service that is started using the startService()
method continues to run even if the component that started it is destroyed. Apart from that, there’s one more way in which the application starts MyService
which is via the one and only broadcast receiver com.XPhantom.id.BootReceiver
present in this application.
android.intent.action.BOOT_COMPLETED
is a broadcast action that is sent by the system when the device completes the booting process and becomes fully operational. It starts the service MainService
when the device completes the booting process. Now, let’s proceed with analyzing the service.
It renders a new view on the screen that looks like This view will also be shown after rebooting the device because the service
MainService
is also started at system startup. The password to remove this view is Abdullah@
which is checked right here.
1
2
3
4
5
6
7
8
9
10
11
12
public void onClick(View view) {
if (this.this$0.e1.getText().toString().equals("Abdullah@")) {
this.this$0.windowManager.removeView(this.this$0.myView);
try {
this.this$0.context.startService(new Intent(this.this$0.context, Class.forName("com.XPhantom.id.MyService")));
return;
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.getMessage());
}
}
this.this$0.e1.setText("");
}
Entering this password into the prompt removes the overlapping view.