Site icon GIXtools

Mandrake spyware sneaks onto Google Play again, flying under the radar for two years

The Mandrake application from the previous campaign on Google Play

Introduction

In May 2020, Bitdefender released a white paper containing a detailed analysis of Mandrake, a sophisticated Android cyber-espionage platform, which had been active in the wild for at least four years.

In April 2024, we discovered a suspicious sample that appeared to be a new version of Mandrake. Ensuing analysis revealed as many as five Mandrake applications, which had been available on Google Play from 2022 to 2024 with more than 32,000 installs in total, while staying undetected by any other vendor. The new samples included new layers of obfuscation and evasion techniques, such as moving malicious functionality to obfuscated native libraries, using certificate pinning for C2 communications, and performing a wide array of tests to check if Mandrake was running on a rooted device or in an emulated environment.

Our findings, in a nutshell, were as follows.

Kaspersky products detect this threat as

HEUR:Trojan-Spy.AndroidOS.Mandrake.*

.

Technical details

Background

The original Mandrake campaign with its two major infection waves, in 2016–2017 and 2018–2020, was analyzed by Bitdefender in May 2020. After the Bitdefender report was published, we discovered one more sample associated with the campaign, which was still available on Google Play.

The Mandrake application from the previous campaign on Google Play

In April 2024, we found a suspicious sample that turned out to be a new version of Mandrake. The main distinguishing feature of the new Mandrake variant was layers of obfuscation designed to bypass Google Play checks and hamper analysis. We discovered five applications containing Mandrake, with more than 32,000 total downloads. All these were published on Google Play in 2022 and remained available for at least a year. The newest app was last updated on March 15, 2024 and removed from Google Play later that month. As at July 2024, none of the apps had been detected as malware by any vendor, according to VirusTotal.

Mandrake samples on VirusTotal

Mandrake samples on VirusTotal

Mandrake samples on VirusTotal

Applications

Package name
App name
MD5
Developer
Released
Last updated on Google Play
Downloads

com.airft.ftrnsfr

AirFS

33fdfbb1acdc226eb177eb42f3d22db4

it9042
Apr 28,
2022
Mar 15,
2024
30,305

com.astro.dscvr

Astro Explorer

31ae39a7abeea3901a681f847199ed88

shevabad
May 30,
2022
Jun 06,
2023
718

com.shrp.sght

Amber

b4acfaeada60f41f6925628c824bb35e

kodaslda
Feb 27,
2022
Aug 19,
2023
19

com.cryptopulsing.browser

CryptoPulsing

e165cda25ef49c02ed94ab524fafa938

shevabad
Nov 02,
2022
Jun 06,
2023
790

com.brnmth.mtrx

Brain Matrix

kodaslda
Apr 27,
2022
Jun 06,
2023
259

Mandrake applications on Google Play

Mandrake applications on Google Play

We were not able to get the APK file for

com.brnmth.mtrx

, but given the developer and publication date, we assume with high confidence that it contained Mandrake spyware.
Application icons

Application icons

Malware implant

The focus of this report is an application named AirFS, which was offered on Google Play for two years and last updated on March 15, 2024. It had the biggest number of downloads: more than 30,000. The malware was disguised as a file sharing app.

AirFS on Google Play

AirFS on Google Play

According to reviews, several users noticed that the app did not work or stole data from their devices.

Application reviews

Application reviews

Infection chain

Like the previous versions of Mandrake described by Bitdefender, applications in the latest campaign work in stages: dropper, loader and core. Unlike the previous campaign where the malicious logic of the first stage (dropper) was found in the application DEX file, the new versions hide all the first-stage malicious activity inside the native library

libopencv_dnn.so

, which is harder to analyze and detect than DEX files. This library exports functions to decrypt the next stage (loader) from the

assets/raw

folder.
Contents of the main APK file

Contents of the main APK file

Interestingly, the sample

com.shrp.sght

has only two stages, where the loader and core capabilities are combined into one APK file, which the dropper decrypts from its assets.

While in the past Mandrake campaigns we saw different branches (“oxide”, “briar”, “ricinus”, “darkmatter”), the current campaign is related to the “ricinus” branch. The second- and third-stage files are named “ricinus_airfs_3.4.0.9.apk”, “ricinus_dropper_core_airfs_3.4.1.9.apk”, “ricinus_amber_3.3.8.2.apk” and so on.

When the application starts, it loads the native library:

Loading the native library

Loading the native library

To make detection harder, the first-stage native library is heavily obfuscated with the OLLVM obfuscator. Its main goal is to decrypt and load the second stage, named “loader“. After unpacking, decrypting and loading into memory the second-stage DEX file, the code calls the method

dex_load

and executes the second stage. In this method, the second-stage native library path is added to the class loader, and the second-stage main activity and service start. The application then shows a notification that asks for permission to draw overlays.

When the main service starts, the second-stage native library

libopencv_java3.so

is loaded, and the certificate for C2 communications, which is placed in the second-stage assets folder, is decrypted. The treat actors used an IP address for C2 communications, and if the connection could not be established, the malware tried to connect to more domains. After successfully connecting, the app sends information about the device, including the installed applications, mobile network, IP address and unique device ID, to the C2. If the threat actors find their target relevant on the strength of that data, they respond with a command to download and run the “core” component of Mandrake. The app then downloads, decrypts and executes the third stage (core), which contains the main malware functionality.

Second-stage commands:

Command
Description

start

Start activity

cup

Set wakelock, enable Wi-Fi, and start main parent service

cdn

Start main service

stat

Collect information about connectivity status, battery optimization, “draw overlays” permission, adb state, external IP, Google Play version

apps

Report installed applications

accounts

Report user accounts

battery

Report battery percentage

home

Start launcher app

hide

Hide launcher icon

unload

Restore launcher icon

core

Start core loading

clean

Remove downloaded core

over

Request “draw overlays” permission

opt

Grant the app permission to run in the background

Third stage commands:

Command
Description

start

Start activity

duid

Change UID

cup

Set wakelock, enable Wi-Fi, and start main parent service

cdn

Start main service

stat

Collect information about connectivity status, battery optimization, “draw overlays” permission, adb state, external IP, Google Play version

apps

Report installed applications

accounts

Report user accounts

battery

Report battery percentage

home

Start launcher app

hide

Hide launcher icon

unload

Restore launcher icon

restart

Restart application

apk

Show application install notification

start_v

Load an interactive webview overlay with a custom implementation of screen sharing with remote access, commonly referred to by the malware developers “VNC”

start_a

Load webview overlay with automation

stop_v

Unload webview overlay

start_i, start_d

Load webview overlay with screen record

stop_i

Stop webview overlay

upload_i, upload_d

Upload screen record

over

Request “draw overlays” permission

opt

Grant the app permission to run in the background

When Mandrake receives a

start_v

command, the service starts and loads the specified URL in an application-owned webview with a custom JavaScript interface, which the application uses to manipulate the web page it loads.

While the page is loading, the application establishes a websocket connection and starts taking screenshots of the page at regular intervals, while encoding them to base64 strings and sending these to the C2 server. The attackers can use additional commands to adjust the frame rate and quality. The threat actors call this “vnc_stream”.  At the same time, the C2 server can send back control commands that make application execute actions, such as swipe to a given coordinate, change the webview size and resolution, switch between the desktop and mobile page display modes, enable or disable JavaScript execution, change the User Agent, import or export cookies, go back and forward, refresh the loaded page, zoom the loaded page and so on.

When Mandrake receives a

start_i

command, it loads a URL in a webview, but instead of initiating a “VNC” stream, the C2 server starts recording the screen and saving the record to a file. The recording process is similar to the “VNC” scenario, but screenshots are saved to a video file. Also in this mode, the application waits until the user enters their credentials on the web page and then collects cookies from the webview.

The

start_a

command allows running automated actions in the context of the current page, such as swipe, click, etc. If this is the case, Mandrake downloads automation scenarios from the URL specified in the command options. In this mode, the screen is also recorded.

Screen recordings can be uploaded to the C2 with the

upload_i

or

upload_d

commands.

The main goals of Mandrake are to steal the user’s credentials, and download and execute next-stage malicious applications.

Data decryption methods

Data encryption and decryption logic is similar across different Mandrake stages. In this section, we will describe the second-stage data decryption methods.

The second-stage native library

libopencv_java3.so

contains AES-encrypted C2 domains, and keys for configuration data and payload decryption. Encrypted strings are mixed with plain text strings.

To get the length of the string, Mandrake XORs the first three bytes of the encrypted array, then uses the first two bytes of the array as keys for custom XOR encoding.

Strings decryption algorithm

Strings decryption algorithm

The key and IV for decrypting AES-encrypted data are encoded in the same way, with part of the data additionally XORed with constants.

AES key decryption

AES key decryption

Mandrake uses the OpenSSL library for AES decryption, albeit in quite a strange way. The encrypted file is divided into 16-byte blocks, each of these decrypted with AES-CFB128.

The encrypted certificate for C2 communication is located in the

assets/raw

folder of the second stage as a file named

cart.raw

, which is decrypted using the same algorithm.

Installing next-stage applications

When Mandrake gets an

apk

command from the C2, it downloads a new separate APK file with an additional module and shows the user a notification that looks like something they would receive from Google Play. The user clicking the notification initiates the installation process.

Android 13 introduced the “Restricted Settings” feature, which prohibits sideloaded applications from directly requesting dangerous permissions. To bypass this feature, Mandrake processes the installation with a “session-based” package installer.

Installing additional applications

Installing additional applications

Sandbox evasion techniques and environment checks

While the main goal of Mandrake remains unchanged from past campaigns, the code complexity and quantity of the emulation checks have significantly increased in recent versions to prevent the code from being executed in environments operated by malware analysts. However, we were able to bypass these restrictions and discovered the changes described below.

The versions of the malware discovered earlier contained only a basic emulation check routine.

Emulator checks in an older Mandrake version

Emulator checks in an older Mandrake version

In the new version, we discovered more checks.

To start with, the threat actors added Frida detection. When the application starts, it loads the first-stage native library

libopencv_dnn.so

. The

init_array

section of this library contains the Frida detector function call. The threat actors used the DetectFrida method. First, it computes the CRC of all libraries, then it starts a Frida detect thread. Every five seconds, it checks that libraries in memory have not been changed. Additionally, it checks for Frida presence by looking for specific thread and pipe names used by Frida. So, when an analyst tries to use Frida against the application, execution is terminated. Even if you use a custom build of Frida and try to hook a function in the native library, the app detects the code change and terminates.

Next, after collecting device information to make a request for the next stage, the application checks the environment to find out if the device is rooted and if there are analyst tools installed. Unlike some other threat actors who seek to take advantage of root access, Mandrake developers consider a rooted device dangerous, as average users, their targets, do not typically root their phones. First, Mandrake tries to find a su binary, a SuperUser.apk, Busybox or Xposed framework, and Magisk and Saurik Substrate files. Then it checks if the system partition is mounted as read-only. Next, it checks if development settings and ADB are enabled. And finally, it checks for the presence of a Google account and Google Play application on the device.

C2 communication

All C2 communications are maintained via the native part of the applications, using an OpenSSL static compiled library.

To prevent network traffic sniffing, Mandrake uses an encrypted certificate, decrypted from the

assets/raw

folder, to secure C2 communications. The client needs to be verified by this certificate, so an attempt to capture SSL traffic results in a handshake failure and a breakdown in communications. Still, any packets sent to the C2 are saved locally for additional AES encryption, so we are able to look at message content. Mandrake uses a custom JSON-like serialization format, the same as in previous campaigns.

Example of a C2 request:

node #1
{
  uid "a1c445f10336076b";
  request "1000";
  data_1 "32|3.1.1|HWLYO-L6735|26202|de||ricinus_airfs_3.4.0.9|0|0|0||0|0|0|0|Europe/Berlin||180|2|1|41|115|0|0|0|0|loader|0|0|secure_environment||0|0|1|0||0|85.214.132.126|0|1|38.6.10-21 [0] [PR] 585796312|0|0|0|0|0|";
  data_2 "loader";
  dt 1715178379;
  next #2;
}
node #2
{
  uid "a1c445f10336076b";
  request "1010";
  data_1 "ricinus_airfs_3.4.0.9";
  data_2 "";
  dt 1715178377;
  next #3;
}
node #3
{
  uid "a1c445f10336076b";
  request "1003";
  data_1 "com.airft.ftrnsfrnncom.android.calendarn[redacted]ncom.android.stknn";
  data_2 "";
  dt 1715178378;
  next NULL;
}

Example of a C2 response:

node #1
{
  response "a1c445f10336076b";
  command "1035";
  data_1 "";
  data_2 "";
  dt "0";
  next #2;
}
node #2
{
  response "a1c445f10336076b";
  command "1022";
  data_1 "20";
  data_2 "1";
  dt "0";
  next #3;
}
node #3
{
  response "a1c445f10336076b";
  command "1027";
  data_1 "1";
  data_2 "";
  dt "0";
  next #4;
}
node #4
{
  response "a1c445f10336076b";
  command "1010";
  data_1 "ricinus_dropper_core_airfs_3.4.1.9.apk";
  data_2 "60";
  dt "0";
  next NULL;
}

Mandrake uses opcodes from 1000 to 1058. The same opcode can represent different actions depending on whether it is used for a request or a response. See below for examples of this.

Attribution

Considering the similarities between the current campaign and the previous one, and the fact that the C2 domains are registered in Russia, we assume with high confidence that the threat actor is the same as stated in the Bitdefender’s report.

Victims

The malicious applications on Google Play were available in a wide range of countries. Most of the downloads were from Canada, Germany, Italy, Mexico, Spain, Peru and the UK.

Conclusions

The Mandrake spyware is evolving dynamically, improving its methods of concealment, sandbox evasion and bypassing new defense mechanisms. After the applications of the first campaign stayed undetected for four years, the current campaign lurked in the shadows for two years, while still available for download on Google Play. This highlights the threat actors’ formidable skills, and also that stricter controls for applications before being published in the markets only translate into more sophisticated, harder-to-detect threats sneaking into official app marketplaces.

Indicators of Compromise

File Hashes
141f09c5d8a7af85dde2b7bfe2c89477
1b579842077e0ec75346685ffd689d6e
202b5c0591e1ae09f9021e6aaf5e8a8b
31ae39a7abeea3901a681f847199ed88
33fdfbb1acdc226eb177eb42f3d22db4
3837a06039682ced414a9a7bec7de1ef
3c2c9c6ca906ea6c6d993efd0f2dc40e
494687795592106574edfcdcef27729e
5d77f2f59aade2d1656eb7506bd02cc9
79f8be1e5c050446927d4e4facff279c
7f1805ec0187ddb54a55eabe3e2396f5
8523262a411e4d8db2079ddac8424a98
8dcbed733f5abf9bc5a574de71a3ad53
95d3e26071506c6695a3760b97c91d75
984b336454282e7a0fb62d55edfb890a
a18a0457d0d4833add2dc6eac1b0b323
b4acfaeada60f41f6925628c824bb35e
cb302167c8458e395337771c81d5be62
da1108674eb3f77df2fee10d116cc685
e165cda25ef49c02ed94ab524fafa938
eb595fbcf24f94c329ac0e6ba63fe984
f0ae0c43aca3a474098bd5ca403c3fca

Domains and IPs
45.142.122[.]12
ricinus[.]ru
ricinus-ca[.]ru
ricinus-cb[.]ru
ricinus-cc[.]ru
ricinus[.]su
toxicodendron[.]ru

Source:: Securelist

Exit mobile version