Content:
Intro
Back in 2017, Spy Note was discovered posing as the Netflix app. It has RAT capabilities that allow it to perform malicious actions on Android devices. In January 2023, a new variant of Spy Note was found impersonating well-known mobile apps like WhatsApp, Facebook, and Google Play, as well as more generic apps such as wallpaper apps, productivity apps, and even gaming apps. In this blog post, we will analyze most of the functionalities it performs and explore how it can compromise user privacy and critical data.
Entry Point
Let’s first look at the
AndroidManifest.xml
file to have an overview of the application’s classes and
definitions. The pre-defined following 31 permissions was
assigned to the app and most importantly gives the application
the ability to do the following:
- Send SMS messages
- Read call log
- Read contact list
- Access Camera and percise device’s location
- Record audio from the device’s microfone
- Disable lock screen
- Read/Write to external storage
- Ability to install and remove applications
- Access to internet and wifi networks
As you can see below, the malware implements some sort of obfuscation on the classes and function names. Digging deeper, you’ll notice that the obfuscation technique is just an insertion of random chars in the middle of the class or method name.
Therefore,
Mylyuntblmikcenkxceinxkcnkcdjwktzpuzlzdnjbmjtudkgqxb14Application
, which is the entry activity class, will be
MyApplication
. Next, cleaning all other classes’ names so that we can easily
continue analyzing tha malware.
Some of the classes are not obfuscated as we described and kept it as it is.
Scheduler Run
In the entry class, the app has a well-implemented trick to keep
itself running. It registers a
Thread.setDefaultUncaughtExceptionHandler
callback, which tells the JVM if any unhandled
exception has occurred. The application schedules itself to run
again after a second via the
AlarmManager
system service, as you can see in the snippet below.
It also keeps track of the exception details that occur while
it’s running via the
getExceptionInformation
function.
Main Activity
As described, the scheduler was set with an intent with this
class
xtkxxuojslebyxwckonorenubwmjxgrdfwrnbhiccrpdhunfel31
, so I renamed it
MainActivity
. While looking at the
onCreate
method,
jadx
wouldn’t be able to decompile it. So, lets look at its
smali
code. It first gets the screen display width and height and
write those value into
SharedPreferences
via
_MySettings
class. Then, it performs some default emulator checks via
Anti_emu
,
isEmu_DIV_ID_lator
, and
AsknoEmu
.
As you can see in
isEmu_DIV_ID_lator
, the strings have the same obfuscation technique and it
deobfuscates them at runtime. Deobfuscation leads to some
generic emulator names.
I’ve demonstrated such methods in this
blog post.
The
AsknoEmu
method propmts a message of emulator detection with different
languages. Main activity also requests auto start and draw over
apps permissions to work properly in the background.
After that, it initializes
WebView
with
setJavaScriptEnabled
being enabled which loads the following URL
https://appfreelancer-87696.web.app/
that was found in the code and was still up and running.
C2 Server
Back to
MyApplication
, while an uncaught exception is occurring, the malware sends
the exception error details to this method:
uyzcwzjgtnouhyxrvjdiqefnzxvpmlzgqywbflfzjtevyyorhz52
, which is a method under a service class named
wsfokmvmcshlqtqmbcoglszscsewjugqxkmygzrkdiudhqjigs38
. Digging deeper into this service, a connection function was
found at the end of the class. Additionally, the C2 server IP
157.10.203.155
and port
7771
were also found, base64 encoded, in another service named
uooxuybinieguhhahsxdwslzrhshusblbobbbjtkftrljhdkjr71
.
Looking again at
MainConnectionService
, It creates a connection to the C2 and encodes any meesage
with Gzip before sending it. The first meesage it sends to the
C2 contains the following
-1[ip]:[port]:AppData:system_info:system_config:meta_data:[ip]:11000011:[CR]:V4:
.
At the time of writing this blog, the C2 server seems down or uses the same port, as it appeared in wireshark, with another service/connection. So, I had to simulate my machine as a C2 with the same ip.
Spying Capabilities
The spyware utilizes various services and broadcast receivers to ensure its functionality remains active. So, I set up a Python server to capture the messages it sends.
The spyware seems to track the applications a user opens and sends this information to the C2 server.
It also includes a recording and logging feature to track the
user’s activity and store it encrypted in the
/Config/sys/apps/log
directory. The encryption utility class was found with a key
that uses plain
AES/ECB
algorithm.
Persistance
In addition to the
uncaughtExceptionHandler
callback, the spyware persist itself by controling the uninstall
cancel button whenever you try to uninstall it via UI. The only
way to uninstall it is via
adb uninstall
command though.
It also requests auto start permissions in order to continue running even after the device is rebooted.
Device Full Control
The Spy Note extends a full
AccessibilityService
class that will do anything on the user’s device that includs:
- Monitoring UI interactions.
- Manipulate device security settings.
- Perform device’s custom actions.
- Capture visited URLs and screen gestures.
- Request device’s administrator.
In Adnroid,
AccessibilityService
is a special service designed to help apps interact with the
user interface in ways that are useful for accessibility
purposes, such as for users with disabilities. Threat actors and
malware authors abuse these features to control the user’s
device rather in just few lines of code.
It also has controlling capabilities for each device manefacturer (Xiaomi, Oppo, Samsung, etc.) as seen below.
Screen Capture
One of the main services are used to capture screenshots and
send it to the C2 server. The images below shows the scrennshot
was stored in an
ArrayList
and the items was added in it as
Bitmap
via another
ImageReader.OnImageAvailableListener
class.
Another background service was used to record conversations via
device’s microphone and it has been used in
MainConnectionService
and saves the audio files in the external storage directory
/Config/sys/apps/rc/
.
Device Unlock
After some time digging into what the spyware can also do, I
found another trick that unlocks the devices whenever the user
leaves it. It records the screen gestures click positions when
the user trying to unlock the device and save it in
/Config/sys/apps/tch/UNLOCK.json
file. Then, it loads the points again to unlock the device.
Here’s the
UNLOCK.json
files that was found during the analysis. It turns out, it
captured the points when I tried to enter the password wrong
multiple times and the last 5 ponts was the correct ones after
simulating it on the emulator.
Note that, the screen view is starting from the top left corner of the display.
Camera and Video Capture
One more service is used to capture live video from the device’s
camera and then save the video frames for later use. When an
Android application requests to use the camera to capture images
or videos, it displays them on a
SurfaceView
. This is the typical usage of the
SurfaceHolder
class, as seen in the image below.
Stealing User’s Credentials
Further analysis shows that the spyware is awaiting special
commands from the C2 server. Most commands are found in a hidden
background service function. One of these commands starts with
lnk<*>
; if so, it is followed by a link to open via a crafted
WebView
Activity that inserts malicious js code on the fly and steals
any inputs the user enters, along with their cookies. After
that, the collected data, along with the visited link, will be
saved into a file in the
/Config/sys/apps/Data
directory.
Here’s the formatted stealer script below.
Command Execution
In addition to the functionalities described above, Spy Note can also execute commands sent by the C2 on the affected device and then send the results back to the C2 server.
OTP and Contacts Exfiltration
The Spy Note also requests the
android.permission.READ_SMS
permission, even though there is no indication of it collecting
SMS messages from the user’s device in this version. Instead, it
was found listening for any verification SMS sent to the device
via the
SmsRetriever
API. This API is part of Google’s Play services and is used to
retrieve authentication-based SMS (such as in the case of a
OTP).
Besides the OTP retriever capability, it also exfiltrates all the contacts stored on the device and send it one by one via SMS to a specific phone number sent by the C2 server.
Conclusion
There are other unmentioned functionalities, such as maintaining Wi-Fi connections when the device is idle and creating Wi-Fi Peer-to-Peer (Wi-Fi Direct) communication, which allows devices to interact with each other without needing an access point (router). Spy Note: With all these capabilities, it functions somewhat like a Remote Access Tool (RAT). It also has different variants that will continue to spread, and threat actors will keep using it to collect critical user data. As a normal user, you should avoid installing games or applications from unknown sources, other than legitimate app stores like Google Play.