# SpyNote in action: how a mobile spyware trojan is created, deployed and examined Natalia Kotova · Forensic Science Centre of the Yaroslavl Regional Police, EKC UMVD MOSCOW FORENSICS DAY ’25 · Day 1 — Thursday, 11 September 2025: digital forensics day · Scheduled 15:35–16:05 · In the recording 03:00:18–03:30:22 Talk transcript · https://2025.moscow-forensics-day.workers.dev/en/transcript/08-kotova Summary: https://2025.moscow-forensics-day.workers.dev/en/summary/08-kotova · Slides: https://2025.moscow-forensics-day.workers.dev/en/slides/07-kotova-spynote · Watch from 03:00:18: https://youtu.be/4V7Wez3L_58?t=10818 --- ## Moderator's introduction So, those of you who come to our events regularly, including the events we hold in the winter, that is, "Digital Forensics 2025", which we held this year. And you all surely remember that back then, in the roast zone, we had quite a heated discussion. And actually, the intro I'd written for the next talk was completely different. But today, before your eyes, on stage, young talent: Natalia Kotova from the EKC of the Yaroslavl Region. Let's welcome her with a big round of applause. She'll present a topic that's on everyone's lips today. SpyNote. So, as I promised, here's the clicker. Flip through like this. The bottom one's for slides. Here's the mic. There you go, please begin. ## Talk and Q&A Good afternoon, all. Thank you for coming. I'd also like to welcome those watching the online stream. Today is my first time on stage, and it's a great honor for me to speak at an event like this in front of specialists of this caliber. Colleagues, the talk turned out quite packed, so those in the back rows, don't be shy, come sit closer, it'll be interesting. So, first, let me introduce myself. I'm an expert in computer and radio-engineering forensics and research at the EKC MVD of Russia for the Yaroslavl Region. A year ago I graduated from the Ministry's university with a specialization in computer forensic examination, so I've been performing them for a year now. When I started work, the first thing I ran into was a flood of examinations related to phone fraud. I don't think I need to say anything about how pressing this problem is. And it just so happened that what came up for examination most often was SpyNote. Briefly, what it is. SpyNote is the name of a threat family. You can see the full antivirus verdict on the slide. It's malicious software of the RAT trojan class for devices on the Android platform. According to Kaspersky's reports, for several years now SpyNote has been in the top 10 verdicts and its popularity is growing steadily. As you can see, it's been around a long time. In 2022, the source code of its builder leaked online, of one of the versions, which only increased its popularity. Most often, SpyNote is used to intercept SMS messages with confirmation codes. The cover stories vary. Doctor's appointment booking, an antivirus, a parcel tracker. On the slide you can see samples of the apps that were found on the devices under examination. Only the icons and names change. At the same time, SpyNote has a fairly broad set of features. I suggest we take a look at its capabilities in action. Without any VPN or SMS registration, online you can download the SpyNote builder, version 6.4. It's a fairly old version, possibly the very one that leaked. The APK files it builds differ from the ones seen in the wild, but they are fully functional. So, you can create your own trojan in a few steps. First, pick an icon, a name, and a version. Second, configure the host address and port. Third, select additional properties and build the APK file. All of this happens automatically. Binding to another APK is also available, in which case the resources of the other app are included in the package. After the app is installed on the device and granted all permissions, the infected device shows up in the admin panel. In the drop-down list, you can select the available modules. For brevity, I'll show only the most interesting ones. The first three modules on the slide are for viewing SMS message contents. By the way, I want to note that sending SMS is not supported in this version. Also viewing the call history and viewing details of contacts and phone numbers. Next we see a file manager that lets you interact with the file system without root access. Here you can copy, delete, create, and add new files. There's also covert access to the cameras. It's invisible to the user, and it works even with the screen locked. Another interesting feature is the keylogger. It involves logging every event of the user's interaction with the system shell. For example, opening and closing apps, navigating the system, notifications, including system ones, keyboard input contents, and so on. All of this not only expands the possibilities for user actions, for tracking the user's actions, but also makes it possible to intercept sensitive information. The app also has access to some device settings. For example, you can lock the screen remotely, do a factory reset, and even set a lock screen password. All of this without any user confirmation. I tested it myself. Other features include access to geolocation, the ability to make phone calls, microphone access, a chat with the user, a terminal, and access to account information. Now let's talk about doing forensic examinations. The typical questions for such examinations are the presence of files detected by antivirus software. And nothing else, no "malicious viruses". That's the only correct wording of the question. They're also interested in the presence of remote access programs, call and SMS history, message history via messengers and social networks, and web browsing history. At the extraction stage, first of all we need to obtain either a physical image or a full file system. Next, we scan the extracted data with antivirus software, using at least two different tools. If the scan detects an APK file, we perform static and dynamic analysis. And, of course, we review the extracted data. Here I want to draw attention to the importance of studying the timeline. For yourself, you still need to establish the fullest picture of what happened. So we look at and compare, cross-reference all the facts: chats, calls, system artifacts. The most convenient place to do that is the timeline. Now I want to go into more detail on static and dynamic analysis. The main tasks of basic static analysis include extracting and decompiling the APK file, studying the metadata from the AndroidManifest file, namely the package name, version, minimum and target Android versions, analyzing the app's structure based on the manifest file, which includes analyzing activities, services, and receivers, identifying protection methods such as obfuscation and packing, analyzing the source code to identify potential functionality, and analyzing string resources to look for, say, network addresses. The tasks of basic dynamic analysis are, first of all, installing and running in an isolated environment, monitoring the app's behavior: what permissions it requests, how it interacts with the user, what its interface looks like, how it works under different conditions, for example, with and without internet access. Network activity analysis is a must, its main goal being to identify the network addresses the app communicates with. And also file activity analysis, to see what files the app creates or modifies. There was already a question about tools today. For the tasks of static and dynamic analysis, a wide range of tools is available. I think many are familiar to you. To decompile APK files, you can use basic utilities such as apktool, JADX, dex2jar. For example, the GUI version of JADX lets you view the decompiled code and the manifest file. In that case, the analysis rests entirely on the forensic expert. To detect obfuscation methods, APKiD is used, and strings, grep, and other tools are used for searching through strings. For dynamic analysis, first of all we need a virtual environment. There are also plenty of options here. And for network traffic analysis, the choice of tool depends primarily on the network protocols being used. Mostly it's HTTP protocols. In that case a proxy is enough, for example Burp Suite or ZAP. For analyzing TCP and all other packets, Wireshark is of course a better fit. I also can't help but share a find of mine. This is Mobile Security Framework. It's open-source software designed for assessing application security. However, it works quite well for our tasks too. It provides automated static analysis and semi-automated dynamic analysis. The tool isn't universal, but quite convenient for initial analysis, and sometimes it does the job alone. It has a graphical interface, which has become familiar and convenient by now. It's deployed as a Docker container. And it additionally requires an emulator for dynamic analysis. If interested, the link on the slide lets you try its online version for static analysis. Let's look at static analysis in more detail. The main source of information about an app is, of course, the manifest file. Its specification can be found on the official site for Android developers, link at the bottom of the slide. From the root manifest tag we get the app's package name and its version. Next we look at the set of permissions. For example, for the APK we built, we see that the app needs access to contacts, phone, SMS, geolocation. The list on the slide is incomplete. Next the manifest describes the structure. An app must have at least one activity. The intent-filter of this activity, for example MAIN and LAUNCHER, indicates that this is the main activity, accessible via the launcher shortcut, exactly when we tap and the app opens. The app can also have background services, which are described in the service components. For example, our app has a service that is declared as an accessibility service. That means the app can be activated as an accessibility service, and that will let it access, for example, the contents of the user's screen. The app can also have receivers that react to system broadcast events. For example, monitoring incoming SMS and monitoring device boot. But you should understand that all this only indicates that such events are being tracked. To establish exactly what they're used for, and whether they're used at all, you need to look at the code inside the declared classes. Static analysis is convenient to do in Mobile Security Framework. It gives us a fairly extensive report. I'll run through the most essential parts. First comes information about the file and the app, including all its hashes, display name, package name, main activity name, app version. You can also view the decompiled manifest, view the decompiled and even download the decompiled Java source code. Next is the list of permissions with their descriptions and, importantly, with links to the source code where these permissions are used. Next comes the list of Android APIs used. A quick explanation here. The Android API is a set of interfaces provided by the Android system for accessing its functions. Comparing these API calls with, say, the permissions requested in the manifest lets us assess how much these permissions are actually used in the code. Another interesting part is malware analysis. It includes APKiD analysis and behavioral analysis. APKiD analysis reveals the app's protection mechanisms, for example against running in a virtual environment, as well as which tools were used to build the app. Behavioral analysis consists of matching typical code patterns against a rule base and determining the app's potential behavior on that basis. As you can see on the slide, the report lists such matches. They have short labels you can use to orient yourself. And again, links to the source code, with the function highlighted that's responsible for that functionality. The report also includes the results of searching the source code for URLs. But keep in mind that it searches specifically by regular expression. Even if the URL is split in the code, domain separately, protocol separately, it won't find it anymore, but sometimes you get lucky. And it will find a complete URL, if there is one. I'd count it as a drawback that it doesn't search for IP addresses. That would be more convenient than searching for them manually. We'll come back to that. And the report also lists right away the strings found in resources and code. That can be useful, but I wouldn't say it's convenient to look at them there. Let me dwell separately on searching for network addresses. It's quite a relevant task. The main sources for the search are the app's resources and the source code. We can search strings by keywords, for example host, port and others. IP addresses can be searched for by regular expression. If a direct search brings no results, you can start searching the source code by analyzing the standard Java networking methods. Here again, behavioral analysis will help us find them. Also, critically important information is often encrypted or encoded. In that case the code will contain methods responsible for decrypting such values. SpyNote performs its functions exclusively on command from the C2 server. Also, when building the APK file, if you remember, we specified the host and port values. Consequently, the app must contain these values somewhere. And in our sample this information is stored in the resource strings. Here, you can find it here. Let's move on to dynamic analysis. In SpyNote's case I used a combination of Mobile Security Framework, the Android Studio emulator with Android 10, and Wireshark, since SpyNote uses TCP packets to communicate with its server. There's no other way to see it. After installation, the app immediately asks for confirmation in the accessibility menu. Then it redirects you to activating the app as a device administrator. It also creates a folder in the user directory where it stores the APK file we used for binding. And, interestingly, most importantly, the SpyNote log file. If we look at this log file, it contains both text data and Base64-encoded blocks. It writes all its keylogger data there. And by decoding these blocks, for example, we can get app icons. If you test the app without internet access, which is the forensically correct way, you'll only see DNS queries for the C2 server's domain name. That's already enough to discover the address and confirm the results of the static analysis. But with internet it gets more interesting. First our domain, of course, resolves to an IP address, and then a TCP connection is established with it. The data is transmitted in compressed form. If you look at the packet payload, by default a certain set of data is sent that's needed for display in the admin panel. The slide shows an example of how an image file can be extracted from the packet data. You can see the thumbnail here. And further interaction happens exclusively on requests from the server. And for dessert, a bit of forensics. If the app is installed, it's all simple. The data directory will be located in /data/data. Information about the installed app, the installation date and time, its display name, we can get from the database files frosting.db and verify_apps.db. These databases are basically always there. And, of course, the main file containing information about all installed apps is packages.xml. Among other things, it also lists the install initiator and the installer app. It gets more interesting if the app is not installed. In that case, searching by the app's package name comes to the rescue. I generally recommend always doing it, since a lot of interesting artifacts may turn up. And they can differ from one mobile device manufacturer to another. For example, on Samsung devices you can find info on an app's installation and removal in the battery usage log. The Android package manager log contains even more information, including, again, who initiated the installation. Well, what do you do if neither the file nor the app is on the device anymore? Here, not an advertisement, help can come from a built-in antivirus, for example Sberbank's app has one. The file 30.db records information about the detection of the app file, with the verdict, package name and, accordingly, the time. So we can prove a malicious app's presence without it being present. That is, that it was there. If SpyNote was run, its log file will most likely be present on the device. For example, on the slide you can see a fragment of its decoded contents. That brings my talk to an end. The topic is quite broad. I tried to cover all the key points. What came out is a small practical guide that you can use during an examination. Thank you for your attention. I'm ready to answer your questions and discuss everything. Great! — — Most modern malware uses crypters and code obfuscators. As I understand it, the source code here is open, there's nothing like that. But have you faced this in your practice, and how do you deal with it? Also, a question roughly on cryptography. If we have a pinned certificate, SSL pinning, did you do SSL unpinning, anything like that, to read the traffic? — Thanks for the question. Regarding obfuscation. Yes, in SpyNote it's used quite heavily, but here it's really about how much you need to dig into the source code. Whether you have the skills for it, whether you have the time for it and how much you need to dig into the source code. Mostly the obfuscation shows up as enormous, strange, meaningless names for all the classes and variables. So analyzing it manually is quite difficult. That's why I found it convenient to use an automated solution, for example one with behavioral analysis. There you can quickly see where a network socket opens, where the SMS handling is. Again, as much as it's needed. Mostly the task boils down to finding the IP address of the C2 server. And about... repeat the second question? The second is about traffic encryption. If the app uses its own certificate, it encrypts traffic with it, and a substituted one, it won't respond to it, even if we load a Burp CA cert, say, onto the phone, we still won't see the decrypted traffic. Yes, with traffic, look, the thing is, since this type of software is client-server. For example, when conducting forensic examinations we try not to let the samples under examination out onto the internet, and so for the most part we don't really face the task of traffic analysis as such, because, let's say, the probability of getting a response back from the C2 server after some time has passed is, well, fairly low. There have been cases, of course, when the scammers used that chat and wrote to the forensic expert. But usually that's not the task at hand. I gave this example here because I had both the client side of the app and the server side. I could trace that traffic. In this case no encryption is used. Only Gzip compression is used, which is fairly easy to decode to get the contents of the packets. It's just that some apps won't give you the C2 server address if they realize they're offline. They'll make a request to, say, some server API to determine what their external IP address is. If they don't see a response, they won't connect anywhere. Yes, that's a very good question too. In that case there's another option, to avoid letting it onto a real network. If the app simply checks for a network connection, you can, for example, use, say, a pair of virtual machines, where one virtual machine runs a network emulation. That is, for example, the INetSim software lets you emulate a setup where any request will get a positive response from a server with stubs. Then we can pass that kind of check. — — Natalia, thank you very much. That was great. Let's give Natalia another round of applause. We're just pressed for time, but we'll still have the roast part with you.