Analysis of an Info Stealer — Chapter 3: The Android App

Fr4
5 min readJan 26, 2024

--

Introduction & Preface

Concluding the article series, this is the third and final chapter of “Analysis of an Info Stealer.” If you happened to miss the preceding chapters, you can locate them here:

  1. Analysis of an Info Stealer — Chapter 1: The Phishing Website
  2. Analysis of an Info Stealer — Chapter 2: The iOS App

In the first article, I showed how this campaign distributes info stealer apps through phishing sites, targeting both Android and iOS devices. In particular, while some special checks are performed during the download of the app for iOS devices, the situation is different for Android devices.

Technical Analysis

The Android app analyzed in this article is a fake Telegram app downloaded from the phishing website: https:]//telegraming.]pro.

(In the previous article I analyzed the corresponding iOS app downloaded from the same phishing site.)

Figure 1 — Phishing Website used to deliver the info stealer apps

Static Analysis

The starting point for analyzing an Android app is usually the AndroidManifest.xml file, as it contains multiple pieces of information that are useful for obtaining an overview of the app. In particular, it includes:

  1. The Minimum and Target SDK Versions that the app is designed to support. The minimum SDK version indicates the lowest Android version on which the app can run, while the target SDK version is the version for which the app is optimized. This information is useful for example during the dynamic analysis, when it is necessary to decide which version of Android to use for the emulator.
  2. The Permissions used to define the actions or resources that an app can access. These permissions ensure that the app operates securely and adheres to privacy and security standards.
  3. Application Entry Points used to define the various components that make up the app, such as activities, services, and other entry points. Activities, for example, represent different screens in the app, while services handle background tasks independently of the UI.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="420" android:versionName="4.2.0" android:compileSdkVersion="33" android:compileSdkVersionCodename="13" package="com.kou.kaizai" platformBuildVersionCode="33" platformBuildVersionName="13">
<uses-sdk android:minSdkVersion="26" android:targetSdkVersion="33"/>
<uses-feature android:name="android.hardware.telephony" android:required="false"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<permission android:name="com.kou.kaizai.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>
<uses-permission android:name="com.kou.kaizai.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
<application android:theme="@style/Theme.cafe24" android:label="@string/logo_names" android:icon="@mipmap/ic_launcher" android:allowBackup="true" android:supportsRtl="true" android:extractNativeLibs="false" android:fullBackupContent="@xml/backup_rules" android:roundIcon="@mipmap/ic_launcher_round" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:dataExtractionRules="@xml/data_extraction_rules">
<activity android:theme="@style/Theme.cafe24" android:name="com.kou.kaizai.MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:theme="@style/Theme.cafe24" android:name="com.kou.kaizai.ui.LoginActivity"/>
<activity android:theme="@style/Theme.cafe24" android:name="com.kou.kaizai.ui.StartActivity"/>
<provider android:name="androidx.startup.a" android:exported="false" android:authorities="com.kou.kaizai.androidx-startup">
<meta-data android:name="androidx.emoji2.text.aa" android:value="androidx.startup"/>
<meta-data android:name="androidx.lifecycle.ad" android:value="androidx.startup"/>
</provider>
</application>
</manifest>

Analyzing the permissions declared in the AndroidManifest.xml file it is possible to observe that the app would read the:

  • Phone state (android.permission.READ_PHONE_STATE)
  • User’s contacts data (android.permission.READ_CONTACTS)
  • User SMS messages (android.permission.READ_SMS)

If you consult the documentation (https://developer.android.com/reference/android/Manifest.permission), you’ll observe that all three of these permissions are categorized under the ‘Protection Level’ as ‘dangerous.’ This indicates that the app seeks to access data and resources involving the user’s private information. Consequently, a pop-up will be presented to the user, requesting confirmation before proceeding.

Futhermore, inside the AndroidManifest.xml file it is also declared a custom permission:
<permission android:name="com.kou.kaizai.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>

This line indicates that the app requests permission to use “com.kou.kaizai.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION.

Analyzing the activities and in particular the <intent-filter>, it is possible to notice that the entry point is the “com.kou.kaizai.MainActivity” activity.

Figure 2— Jadx-gui decompiled code

Examining the “MainActivity”, the onCreate method sets the content view to a splash screen layout, adjusts system UI visibility, and starts a thread (a) to control the splash screen behavior. Following the code inside the class a , the run method starts theloginActivity activity.

In short, the LoginActivity is responsible for handling the permissions and it also incorporates video playback in the background obtained from this URL: “https://onenumsource.com/PRISM_Onboarding_Clean.mp4”

Figure 3— LoginActivity code

The last activity declared inside the AndroidManifest.xml file and called from the LoginActivity is the StartActivity , that is the “core” of the app.

Inside the run method of the StartActivity class the following methods, which are quite self explanatory, are called:

  • getDeviceInfo() : is used to retrieve the information about the infected device, such as the phone number and model
  • getContacts() : is used to retrieve the contacts saved by the user
  • getSms() : is used to get the SMS messages of the user
Figure 4— StartActivity class code

All this data, once retrieved, are send to the C2 server, through the method postJsonData() that is responsible for making the HTTP POST requests with JSON data.

Figure 5 — postJsonData method and the C2 server URL

Now that we have an overview of what are the purpose of this malicious app and what kind of data are sent to the C2 of the attacker, we can perform a dynamic analysis in order to observe the malware in action.

Dynamic Analysis

When opening the application, as described in the previous section, users are prompted to accept permissions through popups, since the app want to access user’s private information, as shown in Figure 6.

Figure 6 — Installation phases

Once allowed, the app shown a fake loader page, while in the background different data are sent to the C2 server of the threat actors, in particular:

  • Phone number and the model of the device
  • All the contacts (name and phone number)
  • All the SMS messages
Figure 7 — Fake loading activity
Figure 8— Examples of data sent to the C2 server

Conclusions

With this last article I conclude the “Analysis of an Info Stealer” article series, where I analyzed the Android app used by attackers to steal SMS messages and contact numbers from infected users’ devices.

Indicators of Compromise (IOCs)

Filename: telegrampro.apk
Md5: 2683ad74bb37bceec19abc557d2aa7fb
C2 Server: https:]//api.]telegraming.]pro

--

--