Back to Research

Something to Remember Us By Device Confiscated by Russian Authorities Returned with Monokle-Type Spyware Installed

This joint investigation with First Department, a legal assistance organization, found spyware covertly implanted on a phone returned to a Russian programmer accused of sending money to Ukraine after he was released from custody.

Key Findings 

  • This joint investigation with First Department, a legal assistance organization, found spyware covertly implanted on a phone returned to a Russian programmer accused of sending money to Ukraine after he was released from custody.
  • He describes being subjected to beatings and an intense effort to recruit him as an informant for the Russian Federal Security Service (FSB).
  • Our analysis finds that the spyware placed on his device allows the operator to track a target device’s location, record phone calls, keystrokes, and read messages from encrypted messaging apps, among other capabilities.
  • The spyware bears many similarities to the Monokle family of spyware, previously reported on by Lookout Mobile Security, which they attribute to the “Special Technology Center,” a contractor to the Russian government. 
  • Our analysis also finds certain differences from previously-reported samples of Monokle spyware, suggesting that it is either an updated version of Monokle or new software created by reusing much of the same code. 

Read the full report by The First Department here and watch the video.

 

Introduction

The First Department is a legal assistance organization founded by exiled Russian human rights lawyer Ivan Pavlov that specializes in defending those accused of treason and espionage in Russia. Pavlov left Russia in September 2021 after facing persecution for his legal work. The First Department plays an essential role in supporting individuals targeted for repression by the Russian government. The organization has been headed by Dmitry Zair-Bek since May 2022. 

In June 2024, The First Department received a report from Kirill Parubets, a Russian programmer who was released from a 15-day period in administrative detention by Russian authorities. Parubets, who consented to being named in this report, was accused of engaging in money transfers to Ukraine. His Android device had been confiscated at the time his apartment was searched, during which he was subjected to beatings, among other things, to compel him to disclose his device password.

Both Parubets and his spouse were taken into custody and detained. During his detention, Parubets describes being subjected to an intense effort at recruitment as an informant by Russia’s Federal Security Service (the FSB). He was threatened with life imprisonment if he failed to cooperate. The recruitment effort suggests a focused and ongoing interest by FSB in his work and contacts, including in Ukraine.

Following Parubets’ release from detention, his device was returned to him at the Lubyanka building, the FSB’s headquarters. Parubets quickly began observing unusual behavior, including a suspicious notification “Arm cortex vx3 synchronization” on the device, which was an Oukitel WP7 running Android 10. This notification is not a standard notification on this device.

Working with Parubets and his spouse, The First Department examined the device and identified a likely-malicious app that he had not installed, and that appeared to have been introduced onto the phone during his detention. The First Department subsequently contacted the Citizen Lab for assistance with technical analysis. 

 

Technical Analysis

Our analysis confirms that the application identified by The First Department is malicious, and that it appears to be a trojanized version of the genuine Cube Call Recorder application. The genuine (non-malicious) Cube Call Recorder is an app listed in the Google Play Store that is designed to allow an individual to automatically record incoming phone calls, as well as calls within messaging apps. 

Figure 1: The same icon is used by both the spyware and legitimate version of the Cube Call Recorder application.
Malicious App SHA-256

737f60749c1919ad22102be27d52ba199ec4b707a985c42011b22ce0a4512c90

Figure 2: The SHA sum of the malicious version of the app.

Spyware Functionality

First Stage

There are some hints about the functionality of the spyware in the permissions requested by the trojanized app. The spyware requests many permissions that the legitimate version of the application does not, including:

  • Access to location information when the application is not in use
  • Read and send SMS messages
  • Install additional packages
  • Read calendar entries
  • Record screen captures
  • List other applications on the device 
  • Answer phone calls 
  • Get account details 
  • Record video with the camera  

The spyware also shares several permissions with the legitimate application (which are also common to spyware) such as: 

  • Accessing precise location 
  • Recording phone calls 
  • Getting information about the target’s contacts
Permission Trojanized App Legitimate App
Accessing fine location
Recording phone calls
Getting information about the target’s contacts
Access to location information when the application is not in use
Read and send SMS messages
Install additional packages
Read calendar entries
Record screen captures
List other applications on the device 
Answer phone calls
Get account details 
Record video with the camera

Table 1: Differences in permissions between the spyware and the legitimate application it is disguised as.

Most of the malicious functionality of the application is contained in the class com.android.twe1ve, a class that is unique to this sample of spyware and not present in the Cube Call Recorder app available in the Google Play Store. 

Most of the malicious functionality of the application is hidden in an encrypted second stage of the spyware. Once the spyware is loaded onto the phone and executed, the second stage is decrypted and loaded into memory. This type of obfuscation can help hide malicious activity from some antivirus software.

The second stage is a dex file encrypted using simple XOR encryption with a static repeating key. The second stage is stored in a data file called license located in the assets directory of the unpacked apk file. The java class com.catalinagroup.callrecorder.App loads lib/arm64-v8a/library.so, which provides functionality for com.system.info.Info to unpack the second stage. 

  static {       System.loadLibrary("rary");

   }

Figure 3: Java code to load the native ARM library which is responsible for unpacking the second stage of the spyware.

The app then calls into the loaded library to extend the app by attaching assets/library as a base context. 

  public void attachBaseContext(Context context) {       Info.get(context, "license");

       super.attachBaseContext(context);

   }

Figure 4: Java code to load the decrypted license file into memory in the context of the trojanized application.

 

Second Stage 

The second stage of the spyware contains additional core Android application libraries in the  com.android.twe1ve class, as well as importing other common cryptography and Android libraries. It also includes several open source software libraries: an RTMP for real time audio/video streaming, and an SMB library presumably for uploading files taken from the device. 

The second stage contains many common spyware capabilities, including:

  • Location Tracking 
  • Screen capture 
  • Keylogging 
  • Recording calls 
  • Extracting files from the device 
  • Extracting stored passwords 
  • Reading messages from other messaging apps 
  • Adding a new device administrator
  • Injection of Javascript 
  • Executing shell commands 
  • Extracting the device unlock password 

It also contains functionality for decrypting settings and data files which are also stored in the assets directory in seemingly randomly named files.

Interestingly, we find several references to iOS in the code, suggesting the possibility of an iPhone version of this spyware.

MwBi.MwLBLiL = new MwIN.MwKuK.MwKuK.MwIN.Mwuk("settingsName", 11, 2); MwBi.MwiB = new MwIN.MwKuK.MwKuK.MwIN.Mwuk("iosPermissionsName", 11, 3);

Figure 5: Reference to iOS permissions in the settings code.

There are also commands from the command and control infrastructure referencing iOS: “ShowiCloudLogin”, and “GetHealthKit.” These are the same references to iOS which were originally reported by Lookout in 2019

New Monokle Spyware? 

Technical experts at The First Department suspected that this spyware might be related to the Monokle family of spyware, originally reported on by Lookout in 2019. Lookout described Monokle as advanced mobile spyware with connections to Russian threat actors. At that time, Lookout linked Monokle to Special Technology Center, Ltd., a company based in St. Petersburg, Russia. 

Throughout the analysis of the sample provided by The First Department we found key similarities to the original Monokle spyware sample, but also some differences, leading us to assess that this is either an updated version of Monokle, or that it has been created by reusing much of the original Monokle code.

Command & Control Similarities

The most compelling evidence that the app installed on the individual’s device is related to the Monokle sample from the 2019 Lookout report is the overlap in the commands issued by the command and control server, including many of the same exact strings. This sample and the 2019 sample both also use the string BaseSystemCommand as the prefix for all command strings, which appears to be unique to these two samples. 

 

Our Sample Lookout Monokle
BaseSystemResponse_ExecuteShellCommand

BaseSystemResponse_GetApplicationsList

BaseSystemResponse_GetCallsList

BaseSystemResponse_GetLocation

BaseSystemResponse_GetScreenPassword

BaseSystemResponse_GetSmsList

BaseSystemResponse_InstallCertificate

BaseSystemResponse_GetKeyLogging

BaseSystemCommand_InstallApplication

BaseSystemCommand_SetAudioRecordMode

baseSystem.executeShellCommand.

baseSystem.getApplicationsList

baseSystem.getCallsList

baseSystem.getLocation

baseSystem.getScreenPassword

baseSystem.getSmsList

baseSystem.installCertificate

baseSystem.getKeyLogging

baseSystem.installApplication

baseSystem.setAudioRecordMode

Table 2: Selected similarities between command and control commands.

Additionally, the same iOS-related commands present in this sample were also observed by Lookout in their 2019 report. 

Additional Similarities

There are additional similarities between the sample identified by The First Department and the 2019 Monokle spyware sample. However, these additional similarities include several common tactics of spyware and would not be as significant on their own without the unique Command & Control overlaps. 

Use of Similar Folders for Malware Staging

The sample identified by The First Department uses the assets folder for storing other stages of spyware and settings, and decrypting that data with a static repeating XOR key. This is the same TTP used by Monokle according to the report from Lookout. 

Use of Accessibility Settings and Other Similarities

The sample also makes use of accessibility settings, a feature noted in the Lookout report. Many of the other capabilities present in this sample such as geofencing, streaming audio, gathering health kit data, and recording the unlock screen password are all present in Lookout’s reporting on Monokle as well. 

Trojanization/Hijacking of Legitimate Applications

This spyware was packaged as a backdoored version of a legitimate application, which is a common technique. Monokle was also typically packaged as a trojanized version of a legitimate application. 

Differences with the Lookout Monokle Sample

Although the analysis found numerous similarities between this sample and the original reporting on Monokle, there are also some differences that are important to mention. The names of the specific files stored in the assets folder have changed and the encryption of the configuration file is more sophisticated than the 2019 sample. The new sample uses a different key than is used for the second stage, making it much more difficult to decrypt and extract additional Command and Control information.

Some of the permissions have changed as well. The app now requests new permissions such as “ACCESS_BACKGROUND_LOCATION, “INSTALL_PACKAGES”, and “LOCAL_MAC_ADDRESS”. Many third-party application-specific permissions, such as “org.thoughtcrime.securesms.ACCESS_SECRETS”, and “com.android.browser.permission.READ_HISTORY_BOOKMARKS” have been removed. Some Android permissions such as “USE_FINGERPRINT”, and “SET_WALLPAPER” have also been removed.

However, even with these changes, the many significant similarities in operations, functionality, and geopolitical motivations lead us to assess that this is either an updated version of the Monokle spyware or new software created by reusing much of the same code. 

Implications of Device Tampering

It is common for the FSB to engage in targeted digital surveillance against individuals they perceive as threats, such as the use of sophisticated social engineering to steal credentials as described in the Rivers of Phish campaign the Citizen Lab uncovered in partnership with Access Now and multiple regional civil society organizations. Malicious activities that target individuals across the globe often rely on tricking a user into engaging with the attackers. However, the tactics often change when an individual is within physical proximity of the attackers. 

Detention and device confiscation can provide an unique opportunity for an adversary to install spyware without the same technical challenges presented by remote attacks. This opportunity is especially pronounced if the adversary has user-level access to the device and is able to compel the individual to provide credentials and/or device passcodes, as they were in this case.

This case illustrates that the loss of physical custody of a device to a hostile security service like the FSB can be a severe risk for compromise that will extend beyond the period where the security services have custody of the device. In this case, the target noticed several odd behaviors on their device after he was released from detention, such as an unfamiliar and suspicious notification and the presence of an app that he had not installed. However, not every attempt to infiltrate and monitor a device is likely to result in such visible alerts. 

We encourage members of civil society that have lost physical custody of their device to a security service, especially a technically competent service in an authoritarian state like Russia, to seek expert assistance when the device is returned to them. Any person whose device was confiscated and later returned by such services should assume that the device can no longer be trusted without detailed, expert analysis. 

Acknowledgements 

We first wish to acknowledge the bravery of Kirill Parubets for coming forward and sharing the details and samples with The First Department and The Citizen Lab. Thanks to Dmitry Zair-Bek and The First Department for their assistance in this investigation. Thanks to Lookout for their original reporting on Monokle and for sharing additional findings to support this research. 

We thank our colleagues at The Citizen Lab for assistance with preparing, editing, and reviewing this report, with special thanks to Bahr Abdul Razzak, Adam Senft, Siena Anstis & Alyson Bruce. Professor Ron Deibert is the principal investigator of the Citizen Lab and this project was undertaken under an approved University of Toronto research ethics protocol # 37346, “Comparative Analysis of Information Security Threats Experienced by Civil Society.”

 

Appendix – Indicators of Compromise 

 

SHA-256 Sum

737f60749c1919ad22102be27d52ba199ec4b707a985c42011b22ce0a4512c90

Commands sent by the C2 Server

BaseSystemCommand_ApplyAgentUpdate

BaseSystemCommand_ClearResults

BaseSystemCommand_DeleteFile

BaseSystemCommand_DeviceControl

BaseSystemCommand_DeviceReset

BaseSystemCommand_ExecuteShellCommand

BaseSystemCommand_GetAccessibility

BaseSystemCommand_GetAgentInfo

BaseSystemCommand_GetAppUsageStatsList

BaseSystemCommand_GetApplicationsList

BaseSystemCommand_GetCallsList

BaseSystemCommand_GetContactsList

BaseSystemCommand_GetDeviceInfo

BaseSystemCommand_GetEmailsList

BaseSystemCommand_GetFile

BaseSystemCommand_GetFilesList

BaseSystemCommand_GetHealthKit

BaseSystemCommand_GetInstantChatsList

BaseSystemCommand_GetKeyLogging

BaseSystemCommand_GetLocalSettingsList

BaseSystemCommand_GetMeetingsList

BaseSystemCommand_GetMmsList

BaseSystemCommand_GetNotesList

BaseSystemCommand_GetPreparedTaskResultsData

BaseSystemCommand_GetRegistryKeysList

BaseSystemCommand_GetSmsList

BaseSystemCommand_InjectJS

BaseSystemCommand_InstallApplication

BaseSystemCommand_InstallCertificate

BaseSystemCommand_MakeCall

BaseSystemCommand_PrepareFileArchive

BaseSystemCommand_ScheduleConnection

BaseSystemCommand_SendSms

BaseSystemCommand_SetAccessibility

BaseSystemCommand_SetAgentSettings

BaseSystemCommand_SetAgentUid_deprecated

BaseSystemCommand_SetApplicationRestriction

BaseSystemCommand_SetAudioListenMode

BaseSystemCommand_SetAudioRecordMode

BaseSystemCommand_SetAudioStreamingMode

BaseSystemCommand_SetCallDropMode

BaseSystemCommand_SetCallRecordMode

BaseSystemCommand_SetCallbackMode

BaseSystemCommand_SetCatchFiles

BaseSystemCommand_SetCommunicationMode_deprecated

BaseSystemCommand_SetConnectPeriod_deprecated

BaseSystemCommand_SetControlPhones_deprecated

BaseSystemCommand_SetEventActions

BaseSystemCommand_SetFileCrypto_deprecated

BaseSystemCommand_SetGeofencesList

BaseSystemCommand_SetInstantChatAccumMode

BaseSystemCommand_SetKeyLogging

BaseSystemCommand_SetKeychain

BaseSystemCommand_SetLocationTracking

BaseSystemCommand_SetPhotoShotMode

BaseSystemCommand_SetScreenCastRecordMode

BaseSystemCommand_SetScreenPasswordMode

BaseSystemCommand_SetScreenRecordMode

BaseSystemCommand_SetScreenShotMode

BaseSystemCommand_SetServerAddress_deprecated

BaseSystemCommand_SetTransportCrypto_deprecated

BaseSystemCommand_SetUsbTunnelPort_deprecated

BaseSystemCommand_SetVideoRecordMode

BaseSystemCommand_SetVideoStreamingMode

BaseSystemCommand_SetWatchFolders

BaseSystemCommand_ShowMessage

BaseSystemCommand_ShowiCloudLogin

BaseSystemCommand_SqlQuery

BaseSystemCommand_StopScheduledTasks

BaseSystemCommand_ToggleBluetooth

BaseSystemCommand_ToggleGPS

BaseSystemCommand_ToggleWifi

BaseSystemCommand_UninstallApplication

BaseSystemCommand_UploadFileToAgent

BaseSystemResponse_CancelAllCommands

BaseSystemResponse_Error

BaseSystemResponse_ExecuteShellCommand

BaseSystemResponse_GetAccessibility

BaseSystemResponse_GetAccountsList

BaseSystemResponse_GetAgentInfo

BaseSystemResponse_GetAppUsageStatsList

BaseSystemResponse_GetApplicationsList

BaseSystemResponse_GetBrowserBookmarks

BaseSystemResponse_GetBrowserHistory

BaseSystemResponse_GetBrowserTracking

BaseSystemResponse_GetCallsList

BaseSystemResponse_GetCapabilities

BaseSystemResponse_GetContactsList

BaseSystemResponse_GetDeviceInfo

BaseSystemResponse_GetEmailsList

BaseSystemResponse_GetEventTracking

BaseSystemResponse_GetFile

BaseSystemResponse_GetFilesList

BaseSystemResponse_GetGeofencesList

BaseSystemResponse_GetHealthKit

BaseSystemResponse_GetInstantChatsList

BaseSystemResponse_GetInterfacesStates_deprecated

BaseSystemResponse_GetJSOutput

BaseSystemResponse_GetKeyLogging

BaseSystemResponse_GetKeychain

BaseSystemResponse_GetLocalSettingsList

BaseSystemResponse_GetLocation

BaseSystemResponse_GetLocationTracking

BaseSystemResponse_GetMMSList

BaseSystemResponse_GetMeetingsList

BaseSystemResponse_GetNetworkingData_deprecated

BaseSystemResponse_GetNotesList

BaseSystemResponse_GetNotificationsList_deprecated

BaseSystemResponse_GetPreparedTaskResultsList

BaseSystemResponse_GetRegistryKeysList

BaseSystemResponse_GetSMSList

BaseSystemResponse_GetScheduledTasksList

BaseSystemResponse_GetScreenPassword

BaseSystemResponse_GetUserDictList

BaseSystemResponse_SetAudioRecordMode

BaseSystemResponse_SetScreenRecordMode

BaseSystemResponse_SetVideoRecordMode

BaseSystemResponse_SqlQuery

BaseSystemResponse_UploadFileToAgent

 

Fields in Data and Settings Files

      AGENT_SETTINGS(1, "agentSettings"),

       SERVICE_KILLED(2, "serviceKilled"),

       RADIO_INFO(3, "radioInfo"),

       TURN_GPS_ON(4, "turnGpsOn"),

       LOCATION_TRACKING_ON(5, "locationTrackingOn"),

       LOCATION_TRACKING_PERIOD(6, "locationTrackingPeriod"),

       HAVE_SCREEN_CAP_PERMISSION(7, "haveScreenCapPermission"),

       KEY_LOGGING_MODE(8, "keyLoggingMode"),

       ACCESSIBILITY_MODE(9, "accessibilityMode"),

       ACCESSIBILITY_MASKS(10, "accessibilityMasks"),

       SCREEN_UNLOCK_HOOK(11, "screenUnlockHook"),

       SCREEN_CAST_RECORD_PARAMS(12, "screenCastRecordParams"),

       SCREEN_SHOTS_SETTINGS(13, "screenShotsSettings"),

       PHOTO_SHOT_SETTINGS(14, "photoShotSettings"),

       PHOTO_SHOTS_CURRENT_QUANTITY(15, "photoShotsCurrentQuantity"),

       CURRENT_AUDIO_TASK(16, "currentAudioTask"),

       CURRENT_VIDEO_TASK(17, "currentVideoTask"),

       CURRENT_AUDIO_LISTEN_TASK(18, "currentAudioListenTask"),

       LEVEL_SETTINGS(19, "levelSettings"),

       GEOFENCES(20, "geofences"),

       SCHEDULED_COMMANDS(22, "scheduledCommands"),

       COMMANDS(23, "commands"),

       SCHEDULED_COMMANDS_ID_TIME(24, "scheduledCommandsIdTime"),

       LAST_COMMAND_ID(25, "lastCommandId"),

       EVENT_ACTION_LIST(26, "eventActionList"),

       INSTANT_CHAT_ACCUMULATE_MODE(27, "instantChatAccumulateMode"),

       CALL_RECORD_MODE(28, "callRecordMode"),

       CALL_RECORD_SOURCE_PHONE(29, "callRecordSourcePhone"),

       CALL_RECORD_SOURCE_IM(30, "callRecordSourceIM"),

       RECORD_CALL_MASKS(31, "recordCallMasks"),

       DROP_CALL_MASKS(32, "dropCallMasks"),

       APPLICATION_RESTRICTION_LIST(33, "applicationRestrictionList"),

       NEED_IMMEDIATELY_CONNECTION_TIME(34, "needImmediatelyConnectionTime"),

       WATCH_FOLDERS(35, "watchFolders"),

       CATCH_FILES(36, "catchFiles"),

       LAST_DEVICE_ON_TIME(37, "lastDeviceOnTime"),

       TASK_ID_CALL_RECORD(50, "taskIdCallRecord"),

       TASK_ID_CALL_DROP(51, "taskIdCallDrop"),

       TASK_ID_SCREEN_PASSWORD(52, "taskIdScreenPassword"),

       TASK_ID_KEYLOGGING(53, "taskIdKeylogging"),

       TASK_ID_LOCATION_TRACKING(54, "taskIdLocationTracking"),

       TASK_ID_ACCESSIBILITY(55, "taskIdAccessibility"),

       RECS__AUDIO(100, "RECS_AUDIO"),

       RECS__PHOTO(101, "RECS_PHOTO"),

       RECS__VIDEO(102, "RECS_VIDEO"),

       RECS__SCREEN__SHOT(103, "RECS_SCREEN_SHOT"),

       RECS__RESERVED(104, "RECS_RESERVED"),

       RECS__ACCESSIBILITY(105, "RECS_ACCESSIBILITY"),

       RECS__TASK__RESULTS(106, "RECS_TASK_RESULTS"),

       RECS__BACKUP(107, "RECS_BACKUP"),

       RECS__FILE__ARCHIVES(108, "RECS_FILE_ARCHIVES"),

       RECS__CATCH__FILES(109, "RECS_CATCH_FILES"),

       FN__KEY__LOGS(120, "FN_KEY_LOGS"),

       FN__ACCESSIBILITY(121, "FN_ACCESSIBILITY"),

       FN__SPELL(122, "FN_SPELL"),

       FN__RECORDS(123, "FN_RECORDS"),

       FN__SHUTDOWN__TRACKING(124, "FN_SHUTDOWN_TRACKING"),

       FN__DATA__MESSAGES(125, "FN_DATA_MESSAGES"),

       FN__HISTORY(126, "FN_HISTORY"),

       FN__LOCATION__TRACKING(127, "FN_LOCATION_TRACKING"),

       FN__PASSWORD__LIST(128, "FN_PASSWORD_LIST"),

       FN__WATCH__FOLDERS(129, "FN_WATCH_FOLDERS"),

       FN__CATCH__DATA__FILE(130, "FN_CATCH_DATA_FILE"),

       UPDATE_FILE(150, "updateFile"),

       IS_INSTALLED_UPDATE(151, "isInstalledUpdate");

 

Permissions requested by the spyware which are not present in the legitimate version of the application:

android.permission.ACCESS_BACKGROUND_LOCATION

android.permission.ACCESS_NOTIFICATION_POLICY

android.permission.ANSWER_PHONE_CALLS

android.permission.AUTHENTICATE_ACCOUNTS

android.permission.BATTERY_STATS

android.permission.BIND_ACCESSIBILITY_SERVICE

android.permission.BLUETOOTH_ADMIN

android.permission.CALL_PHONE

android.permission.CAMERA

android.permission.CAPTURE_AUDIO_OUTPUT

android.permission.CHANGE_NETWORK_STATE

android.permission.CHANGE_WIFI_STATE

android.permission.GET_ACCOUNTS

android.permission.INSTALL_PACKAGES

android.permission.LOCAL_MAC_ADDRESS

android.permission.MANAGE_EXTERNAL_STORAGE

android.permission.MODIFY_PHONE_STATE

android.permission.PACKAGE_USAGE_STATS

android.permission.PROCESS_OUTGOING_CALLS

android.permission.QUERY_ALL_PACKAGES

android.permission.READ_CALENDAR

android.permission.READ_CALL_LOG

android.permission.READ_FRAME_BUFFER

android.permission.READ_PRIVILEGED_PHONE_STATE

android.permission.READ_SMS

android.permission.RECEIVE_BOOT_COMPLETED

android.permission.RECEIVE_SMS

android.permission.REQUEST_DELETE_PACKAGES

android.permission.REQUEST_INSTALL_PACKAGES

android.permission.SCHEDULE_EXACT_ALARM

android.permission.SEND_SMS

android.permission.TEMPORARY_ENABLE_ACCESSIBILITY

android.permission.WRITE_SECURE_SETTINGS

android.permission.WRITE_SETTINGS