In March 2024, we discovered a campaign targeting users in Russia. The campaign used a previously unknown piece of Android spyware, which we named LianSpy. According to our data, this malware has been active since July 2021 and is capable of recording the user’s screen, stealing user documents, storing call logs, and collecting app lists. The attackers behind this malware are very stealthy: instead of their own infrastructure, they use the Russian cloud service Yandex Disk as a command server and also employ various means of protecting spyware from detection. Several signs suggest that LianSpy is most likely deployed after exploiting an unknown vulnerability or through physical access to the victim’s phone.
Technical details
When launched, the malicious app checks whether it is running as a system app, in which case the necessary permissions are granted automatically. Otherwise, the app requests permissions to display on top of other windows, access notifications, and run in the background, as well as necessary access rights such as reading the contact list and call logs. After receiving all the necessary permissions, the malware checks whether it is running in a debugging environment. If the runtime environment does not show any signs of using a debugger, LianSpy runs its configuration with pre-defined values. The configuration is saved on the device as a set of key-value pairs using SharedPreferences, a built-in Android mechanism that is commonly used to remember application settings. This data remains available even after a device reboot. In the LianSpy configuration, the keys are integer values that correspond to the spyware settings. The full list of configuration parameters with descriptions and default values is provided below.
ID (key) | Description | Default value |
100 | First start | false |
110 | Allow operation when connected to Wi-Fi | true |
111 | Allow operation when connected to a mobile operator's network | true |
113 | Yandex ID of the attacker | Data hidden |
115 | Yandex Disk OAuth token of the attacker | Data hidden |
121 | Collect information about installed applications on the victim's device | true |
123 | Collect call log data | true |
124 | Collect data from contact list | true |
128 | Take screenshots as root using screencap binary | false |
136 | Capture the screen using the Media Projection API | true |
302 | Interval between screenshots in milliseconds | 5000 (5 sec) |
308 | Interval between data exfiltration tasks in milliseconds | 1200000 (20 min) |
400 | A comma-separated list of applications (substrings of package names) for which the spyware should capture the screen via the Media Projection API or take screenshots using the screencap binary. | whatsapp, viber, skype, chrome, vkontakte, telegram, android.gm, gallery, thoughtcrime.securesms, facebook, tencent.mm, snapchat, icq, tencent.mobileqq, imoim, mailapp, instagram, kakao.talk, discord, chrome, internet, browser, dolphin, firefox, opera, safari, uc browser, maxthon, baidu, yandex |
420 | Not used | - |
450 | User ID | - |
After initialization, the spyware hides its icon and registers a built-in broadcast receiver to receive commands from the system. This receiver is responsible for starting and stopping various malicious tasks: screen capture via the Media Projection API, creating screenshots as the root user, data exfiltration, and configuration updates.
LianSpy Registers Malicious Broadcast Receiver
To update the configuration, LianSpy searches the attacker's Yandex Disk every 30 seconds for a file matching the regular expression ^ frame_ . + \ \ \ . png $ . If the file is found, it is downloaded to the application's internal data directory. The malware then decrypts the overlay (data written after the payload) in the downloaded file using a hardcoded AES encryption key. Finally, the configuration updater tries to find a set of substrings in the decrypted payload that modify the LianSpy configuration. The full list of available parameters is provided below.
Substring (command name) | Description |
*con+ | Enable contact list information collection |
*con- | Disable contact list information collection |
*clg+ | Enable call log data collection |
*clg- | Disable call log data collection |
*app+ | Enable collection of information about installed applications |
*app- | Disable collection of information about installed applications |
*rsr+ | Schedule screenshots |
*rsr- | Stop taking screenshots |
*nrs+ | Enable screen recording |
*nrs- | Disable screen recording |
*swl | Set a new list of applications (specified immediately after the command text) in which the spy program should record the screen |
*wif+ | Allow execution if device is connected to Wi-Fi |
*wif- | Prevent execution if device is connected to Wi-Fi only |
*mob+ | Allow execution if device is connected to mobile operator network |
*mob- | Prevent execution if device is connected to mobile operator network only |
*sci | Set screen capture interval in milliseconds |
*sbi | Set the interval between data exfiltration tasks in milliseconds |
The collected data is stored encrypted in the SQL table Con001 , which also contains the record type (device information, contact list, call logs, etc.) and its SHA-256 hash. The data is encrypted using the following scheme:
- The AES key for data encryption is generated using a secure pseudo-random number generator (PRNG). This prevents third parties from reading the data in the event of a timing attack.
- The RSA public key specified in the LianSpy code is used to encrypt the AES key.
Using this scheme, only an attacker who has the private RSA key can decrypt the stolen data.
Camouflage means
LianSpy implements a number of non-standard techniques that allow you to avoid detection.
- Variants of the malware are disguised as either the Alipay app or a system service.
- Since Android 12, the OS has a feature called privacy indicators . Its main purpose is to display an icon in the status bar when sensitive information is being accessed (for example, when a screen recording is in progress). However, the LianSpy developers managed to bypass this protection by adding the cast value to the Android security setting icon_blacklist , which prevents notification icons from being displayed in the status bar.
- LianSpy hides notifications from background services it calls using the NotificationListenerService, which processes notifications and can remove them from the status bar. Below is a list of key phrases used to remove notifications from the status bar.12345running in the backgroundusing batteryв фоновом режимеиспользует батареюиспользуют батарею
- LianSpy can take screenshots using the system command screencap , which is usually used for debugging, but can also be accessed with root privileges. This command does not reveal itself when taking a screenshot, allowing attackers to stealthily intercept the contents of the screen.
- The spy relies heavily on legitimate services (cloud storage and pastebin), so no suspicious network activity will be observed on the infected device.
- LianSpy encrypts stolen data using a secure algorithm. Even if Yandex Disk credentials are obtained during APK analysis, victims cannot be identified.
- The malware uses a modified su binary file, which is required to obtain root access. The analyzed malware samples try to find the mu binary file in the standard su directories . Most likely, this is an attempt by the attacker to hide the fact that root privileges have been activated on the victim's device. This reliance on a modified binary file suggests that this spyware is delivered to the device by exploiting an unknown vulnerability or through physical access to the victim's phone.
Infrastructure
LianSpy does not have its own infrastructure. The malware uses the Yandex Disk service to exfiltrate stolen data and store configuration commands. All victim data is uploaded to a separate folder on Yandex Disk.
It is noteworthy that, in addition to updating the configuration, communication between the command server and LianSpy is carried out unilaterally: the spy no longer receives any commands from Yandex Disk. Depending on the configuration, the program searches for updates and exfiltrates data.
The Yandex Disk service credentials are updated from a pastebin page specified in the code, which may differ from variant to variant. The full list of pastebin pages is provided in the Indicators of Compromise section.
Victims
Considering that the key phrases for filtering notifications are partially written in Russian, and that some of the default configurations of LianSpy variants contain the names of messenger packages that are widely used by Russian users, we assume that this spyware is targeting users from Russia. KSN telemetry data confirms that Russian users have been targeted by LianSpy attacks.
Conclusion
A new Android spyware we’ve dubbed LianSpy has some interesting functionality. In addition to the standard spyware stealing of call logs and app lists, the program can record the screen and stealthily use root privileges. Notably, the malware relies heavily on a renamed su binary , suggesting that this spyware is delivered after another successful attack on the victim’s phone. It’s also worth noting that the default configuration allows LianSpy to capture the screen in a number of instant messengers, suggesting that the attacks are not financially motivated, but rather data-driven – a sure sign of a targeted attack.
The malware only uses legitimate resources such as Yandex Disk and pastebin to exfiltrate data and communicate with the command server, making it difficult to attribute this campaign. This newly discovered Android threat does not resemble other ongoing campaigns targeting Russian users, and we will continue to monitor any related activity.
Indicators of compromise
APK file hashes
084206ec8e6e5684a5acdcbd264d1a41
09088db5640381951e1b4449e930ff11
15222c61978f9133aa34b5972ce84e7e
1ccf5b723c38e30107d55
040f10ce32a 22b013cfb95df6b4ba0d2d40dc4bddf4
23b9e5d4ab90506c6e9a42fa47164b84
36bc97ce040ada7142e4add4eb8cd3dd
38149658e5aba1942a6147b387f79d3f
3a4f780820043a8f855979d2c59f36f2
4c3e81bb8e972eef3c9511782f47bdea
5b16eb23a2f5a41063f3f09bc4ca47
dd 69581e8113eaed791c2b90f13be0981a
707a593863d5ba9b2d87f0c8a6083f70
7de18a7dac0725d74c215330b8febd4e
842d600d5e5adb6ca425387f1616d6c4
86ea1be200219aca0dc985113747d5ea
86f7c39313500abfb12771e0a4f6d47a
8f47283f19514178ceb39e592324695 a 966824d8c24f6f9d0f63b8db41f723b6
99d980a71a58c8ad631d0b229602bbe2 9f22d6bffda3e6def82bf08d0a03b880 a7142ad1b70581c8b232dc6cf934bda4 c449003de06ba5f092ee9a74a3c67e26 d46c5d134a4f9d3cd77b076eb8af28b3 d9e9655013d79c692269aeadcef35e68 da970 92289b2a692789f7e322d7d5112 ec74283d40fd69c8efea8570aadd56dc f13419565896c00f5e632346e5782be4 f37213a7ef3dc51683eec6c9a89e45af f78eaca29e7e5b035dbcbabac29eb18d fa3fecca077f0797e9223676d8a48391 fbc2c4226744c363e62fcfeaec1a47f1