Summary
An analysis and breakdown of a Fradulent RBL application I received through a phishing message. This blog aims to raise awareness about the dangers of installing fraudulent apps on your mobile device and explores how hackers develop and secure their apps to prevent reverse engineering.
The application and its domains have no connection to RBL Bank or any other legitimate bank service. which means its a fraud Application.
The Initial Alert
After taking a break following a busy business week, I suddenly received an SMS in my messaging app that caught my attention.
Dear INDUSIND CREDIT USER Your fees payment of FY CASH POINTS 7800 EXPIRED TODAY is pending. Kindly pay before expired. Click Phishing Link Here.
I quickly recognized it as part of a phishing campaign due to the message structure and the fact that I don’t have an INDUSIND credit card.
It became quite interesting to me at that momement, and I thought, ‘Alright, let’s unpack this and see what the application is actually doing in a victim mobile.
The phishing page
After clicking the link, I was redirected to a phishing page that resembled a Bank Credit Card Reward Points Redemption Page.
I quickly opened my lab and began analyzing the page.
The source code of the phishing page allows us to obtain the malicious android application package.
I downloaded the fake RBI application and, after unpacking it using an Android decompiler, I observed from the Android Manifest file that it was requesting several dangerous permissions from the user.
Permission | Description |
---|---|
CALL_PHONE | Allows the application to make phone calls without user intervention |
SEND_SMS and SEND_NO_CONFIRMATION | Permissions enable the app to send SMS messages with SEND_SMS_NO_CONFIRMATION , which bypasses the user verification |
RECIVE_SMS and RECIEVE_MMS | Permission allows the app to read incoming SMS and MMS messages. |
READ_PHONE_STATE | Grants access to sensitive information about the phone state. including the phone number and network informations |
RECIVE_BOOT_COMPLETED | Allows the appliction to start it services as soon as the device boots up this will allows the fraud app to run in the background without the users knowledge |
ACCESS_NETWORK_STATE | While It can be used to track the device is connected to the internet |
BRODCAST_SMS | Permissions can be used to send broadcast messages related to SMS |
The application includes multiple services, such as SmsService and MessageReceiver, which are associated with banking applications and are designed to intercept sensitive information received via SMS.
Additionally, I noticed that the application uses a service called FirebaseListenerService, which allows it to maintain persistent connections to the server. This service can be used to continuously send or receive data, even when the app is not actively in use.
Observed that an another FirebaseListenerService which is set up to handle background operations related to data synchroztion and location tracking. by setting it as
android:exported="false"
it is restricted from being accessed by other applications.
The receiver MessageReceiver listens for incoming SMS messages and can respond to them.
Upon opening the Java file, I found that the application was heavily obfuscated, making the code unreadable. Using APKid, I discovered that the app is packed with a tool called ApkEncrypter.
https://github.com/FlyingYu-Z/ApkEncryptor
From the Java code observed that the application is importing 2 classes from package com.beingy.encrypt.
import com.beingyi.encrypt.BYDecoder
import com.beingyi.encrypt.StringPool
BYDecoder.Java
package com.beingyi.encrypt;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class BYDecoder {
public static String s1 = "fff";
public static String s2 = "fsghff";
public static String decode() {
String text = StringPool.s1;
String result = decode(text, "#pass");
return result;
}
public static String decode(String text, String pass) {
byte[] result;
int hexlen = text.length();
if (hexlen % 2 == 1) {
hexlen++;
result = new byte[hexlen / 2];
text = "0" + text;
} else {
result = new byte[hexlen / 2];
}
int j = 0;
for (int i = 0; i < hexlen; i += 2) {
result[j] = (byte) Integer.parseInt(text.substring(i, i + 2), 16);
j++;
}
byte[] decrypt = null;
try {
Key key = new SecretKeySpec(pass.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, key);
decrypt = cipher.doFinal(result);
} catch (Exception e) {
e.printStackTrace();
}
return new String(decrypt);
}
}
From the above application snippets i understood that the The BYDecoder class is responsible for decrypting a hex-encoded string using an AES encryption method with a Password.
The second decode() method retrieves a string from StringPool.Java, which contains a list of strings that appear random and encrypted, making them unreadable in their raw form.
StringPool.Java
package com.beingyi.encrypt;
/* loaded from: classes.dex */
public class StringPool {
/* renamed from: uTpImᵔיʾⁱʻٴˆٴˋⁱﹶʻˈʻᴵˋˆـᵔʾﹶᵢˈיﹳʿˈʻـˆinLIJ reason: contains not printable characters */
public static String f191uTpIminLIJ = "5acac0ebc0bd614ee14f044362cb9a65";
/* renamed from: CCxEvᵢٴˑˆᵢˋⁱـᐧʾˉﹳˏ゙ˆᴵᐧᵔʽᐧᐧﹳˉ゙゙ᴵˉʼٴᵎQULgm reason: contains not printable characters */
public static String f20CCxEvQULgm = "db9c50916fb8672b082755625d8ae966";
/* renamed from: wVfccˏˋⁱיˋᵔˆⁱⁱᵔˎʼˏˎⁱᵔـᵔﹶⁱʽـٴˏˎˑᵢٴʿⁱdimeE reason: contains not printable characters */
public static String f204wVfccdimeE = "6d1a6f6d865901e444f099bdf996791d";
/* renamed from: WLLNqᵢⁱˎﹳᵔⁱˊᵎٴﹶʼᐧʽʿˋ゙゙ˊˆʻᴵﹳˈʿיﹳʿʽˊˉjzHTI reason: contains not printable characters */
public static String f100WLLNqjzHTI = "9cd7d79e4e204fc88dc1f6b8c26e6324";
/* renamed from: iOPUeﹳᴵˆˉˏˉˉⁱˑﹶᵎיˋᵢˊᵢﹶˉـˈﹳᵔʾٴˋˏⁱˉٴⁱxRMoj reason: contains not printable characters */
public static String f148iOPUexRMoj = "653aee9b2eac775cb4f0b54dd9cd6bc4";
/* renamed from: jzGKLˏᵎᴵˉᵎˋᐧיʾʾﹳʾˋˏᴵᵎיʻˋʻˏʼﹶᴵˆˊᵔﹳʿcudLy reason: contains not printable characters */
public static String f156jzGKLcudLy = "eb69b9f178045b271c9fa7425dcd4dc7";
/* renamed from: iMNwNʽﹶʼˋᐧˉˋٴᵎʻⁱᵢᴵᵔ゙ٴⁱـˋˑᵔˏʾʼˏˊˎ゙ᴵʾAEniY reason: contains not printable characters */
public static String f147iMNwNAEniY = "176e52dc8675858dd95928cc6ee60f6e";
/* renamed from: yfDGiᵢᵢᴵـᵔˈיˏᵢʽⁱˏˈיˊˊˉʼˆٴ゙゙ᵢʾ゙ʿٴ゙ʿˈELfgo reason: contains not printable characters */
public static String f214yfDGiELfgo = "7de2207d60f10802dda3ae76845bc71dff70f927952c039db32ab22d74eba14511ac16ee909185a99db3129cae47581184bf89cd89ba5c39bd30cbe9f074cf7b";
/* renamed from: XUEdCᴵʾـˑᵎˉ゙ᵢᴵﹳˆˆﹶˈـˑﹶᐧʾʾˈʻˈˎٴˋˈˊkrxxS reason: contains not printable characters */
public static String f105XUEdCkrxxS = "da88b545982ae0021b30b6a6cbf6873c";
From the SRC folder, I found the protected DEX files that contain the main activity files.
Since the DEX files are protected, a password is required to decrypt them. Fortunately, the password used to secure these files was the package name of the fraudulent application.
After decrypting the DEX files, I was able to access the MainActivity.Java and other Java files, as shown in the screenshot below.
MainActiviy.Java
From the MainActivity.java, I discovered that the application includes a form requiring various user inputs, such as CVV, card number, name, mobile number, expiration date, and date of birth. Additionally, it implements input field validation to verify the accuracy of the provided information.
MessageReceiver.Java
The MessageReceiver class listens for incoming SMS messages on the device and extracts relevant data, including the sender, message body, timestamp, and operator information.
After extracting the relevant content from the message, the application uploads this data to the Firebase Database, as shown below.
Based on the assessment above, I concluded that the application collects card input information from users, monitors SMS messages on the device, and uploads this data to a Firebase database, with no other C2C interactions present.
From the application, I was able to obtain the Firebase connection URL and the Google Cloud Storage bucket for the Firebase database.
Dynamic Analysis
After conducting some static analysis at the code level, I decided to install the application on a physical mobile phone for testing purposes. Upon launching the application, the following screen will appear.
Once you enter the data, the second activity will display a success message.
Firebase Database.
I entered some random data into the application for testing. The Firebase URI identified in the static analysis is not secured by the scammers, which enables real-time data capture from the application. This gives me access to all the information stored in the database, including card details of prior victims and their SMS messages.
Previously Captured Messages with otp.
The Last Verdict
I monitored the entire traffic of the application but no luck found . so as a part of last try . i decided to start fuzzing on the firebase url and got an system.json
I decided to halt my analysis at this point.
From the system.json file . i found some information related to the administrator like server status and admin password (not verified), and an indian phone number which is likely to be the administrator’s phone number.
Conclusion
Scammers and hackers are continuously evolving their techniques, and the scenario described above is just one of an easy catch examples. their are many sophisticated campaigns operating online. It is our responsibility to stay vigilant and protect ourselves from these threats to ensure our safety in the digital landscape.
As Generic Message to everyone
-
The primary recommendation is to avoid clicking on suspicious links from text messages, Messenger, WhatsApp, etc.
-
Only download applications from official stores, such as the Play Store, Appstores.
-
Disable installation from unknown sources, and be mindful of the permissions requested.
-
Keep your device’s software up to date and enable Play Protect features, which can help detect a wide range of malware and suspicious applications.
YARA Rule
Leaving a space over here . I will update the YARA rule for detecting similar malicious APKs shortly.
I hope all of you enjoyed and learn something new . will back with another intresting things until then bye …