# A technical analysis of Pegasus for Android – Part 1 **[cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-1](https://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-1)** Summary Pegasus is a spyware developed by the NSO group that was repeatedly analyzed by [Amnesty International and](https://www.amnesty.org/en/latest/research/2021/07/forensic-methodology-report-how-to-catch-nso-groups-pegasus/) [CitizenLab. In this article, we dissect the Android version that was](https://citizenlab.ca/2020/12/the-great-ipwn-journalists-hacked-with-suspected-nso-group-imessage-zero-click-exploit/) [initially analyzed by Lookout in this paper, and we recommend reading it along with this post.](https://info.lookout.com/rs/051-ESQ-475/images/lookout-pegasus-android-technical-analysis.pdf) During our research about Pegasus for Android, we’ve found out that vendors wrongly [attributed some undocumented APK files to Pegasus, as highlighted by a researcher here.](https://twitter.com/maldr0id/status/1492520053702602755) We’ve splitted the analysis into 3 parts because of the code’s complexity and length. We’ve also tried to keep the sections name proposed by Lookout whenever it was possible so that anybody could follow the two approaches more easily. In this part, we’re presenting the initialization of the application (including its configuration), the targeted applications, the commands related to the core functionality, and the methods that Pegasus could use to remove itself from a device. Our contributions consist of dissecting the application deeper than before and explaining additional functionalities that were identified. Technical analysis SHA256: ade8bef0ac29fa363fc9afd958af0074478aef650adeb0318517b48bd996d5d5 We’ve performed the analysis using JD-GUI Java Decompiler and Android Studio. ----- **Initial Launch and Configuration** The application must obtain an initial configuration from an URL found in the Browser history or from a file called “/data/myappinfo” or “/system/ttg”. As we’ll see during the entire analysis, the malware is pretty noisy and logs messages using the Log.i method. Interestingly, the author mentions the JigglyPuff character from Pokemon in the logging function: Figure 1 Figure 2 Firstly, the application tries to parse a config file called “/data/myappinfo” or “/system/ttg” if the first one doesn’t exist: ----- Figure 3 Figure 4 The malware deletes a file called “/data/cksnb.dat” using a binary called “/system/csk”. According to Lookout, this file is present on devices that were previously rooted. The purpose of this binary is to run a command passed as a parameter (such as “rm”) with root privileges: ----- Figure 5 Whether the process finds one of the configuration files mentioned above, it reads an URL that will be deleted from the Browser history. Some of the settings are Base64-encoded and will be decoded using an implementation of the Base64 algorithm: ----- Figure 6 The application reads a token and an “installation” value from the configuration file: ----- Figure 7 Furthermore, the process reads a configuration value called “local” and another one called “userNetwork”, which represents the mobile country code of the victim’s phone: ----- Figure 8 The malware reads a configuration value that specifies whether it should communicate with the C2 server while the phone is roaming. The configuration file also contains commands to be executed by Pegasus: ----- Figure 9 The version of the installed agent (“packageVersion”) and a value called “vulnarbilityIndicator” are also read from the configuration file. The last value is set when requesting an update package, and it would create an mp3 file that exploits the Media Player on the phone, according to our analysis: ----- Figure 10 The agent copies a file called “/data/cksnb.dat” to “/data/data/com.network.android/output.mp3”. As also highlighted below, the mp3 file would exploit a “vulnarbility” [sic] in Media Player: ----- Figure 11 Figure 12 A config value called “url address” will be removed from the browser history. The application extracts a table containing both bookmarks and history items from Browser.BOOKMARKS_URI: ----- Figure 13 As we mentioned before, the application could retrieve the configuration from an URL containing “rU8IPXbn” found in the Browser history, as highlighted in figure 14. ----- Figure 14 The agent parses the target URL and extracts a token (“t=” parameter), a Base64-encoded command and signature (“&c”), the “installation” value (“&b”), the “userNetwork” configuration option (“&d”), and the “windowYuliyus” value (“&r”): ----- Figure 15 The malware expects a valid token and a valid target URL; otherwise, it calls the Log.e method with the “getSettingsFromBH no valid settings on getSettingsFromHistory” message: ----- Figure 16 The agent calls a function that validates the MCC (mobile country code) extracted from the configuration: Figure 17 The getSubscriberId function is utilized to extract the unique subscriber ID. The first 3 digits represent the mobile country code (MCC), which is compared with the value extracted from the configuration: ----- Figure 18 The application verifies whether the “did_we_restart_after_upgrade_already” value, which indicates that the device was rebooted after the installation of Pegasus, is true or false. In the case of no reboot, the application restarts the phone using the “reboot” command: Figure 19 Figure 20 reveals how the “/system/csk” binary is used to run commands with root privileges: ----- Figure 20 The agent uses a regex to parse the target URL and to extract the IP address and the token, as highlighted below: ----- Figure 21 ----- Figure 22 The process calls a function that deletes the target URL from the Browser history based on the IP address extracted above: Figure 23 The malware starts logging some messages before performing the deletion operation: ----- Figure 24 The application retrieves the bookmarks and history items from “Browser.BOOKMARKS_URI” and “Browser.HISTORY_PROJECTION”: ----- Figure 25 The URL containing “rU8IPXbn” is deleted from the Browser history by calling the Browser.deleteFromHistory function: ----- Figure 26 Figure 27 The configuration data is saved in a preference file called “NetworkPreferences” that can be accessed using the Android SharedPreferences APIs. **Targeted Applications** ----- 1. Facebook The database files storing the Facebook messages are made accessible to everyone by running the following commands: chmod 0777 /data/data/com.facebook.katana chmod 0777 /data/data/com.facebook.katana/databases chmod 0777 /data/data/com.facebook.katana/databases/threads_db2 chmod 0777 /data/data/com.facebook.katana/databases/threads_db2-journal The following SQL query is executed: SELECT messages.msg_id, messages.thread_id, messages.timestamp_ms, messages.text, messages.sender, threads.participants from messages INNER JOIN threads ON messages.thread_id=threads.thread_id Figure 28 2. Kakao The database files storing the KakaoTalk chat logs are made accessible to everyone by running the following commands: chmod 0777 /data/data/com.kakao.talk chmod 0777 /data/data/com.kakao.talk/databases chmod 0777 /data/data/com.kakao.talk/databases/KakaoTalk.db chmod 0777 /data/data/com.kakao.talk/databases/KakaoTalk.db-journal The following SQL query is executed: SELECT chat_logs.id, chat_logs.chat_id, chat_logs.created_at, chat_logs.message, chat_logs.user_id, chat_logs.type, c.members FROM chat_logs JOIN chat_rooms c ON chat_logs.chat_id=c.id ----- Figure 29 3. Skype The database files storing the Skype chat messages are made accessible to everyone by running the following commands: chmod 0777 /data/data/com.skype.raider/files/ chmod 0777 /data/data/com.skype.raider/files/main.db chmod 0777 /data/data/com.skype.raider/files/main.db-journal The following SQL query is executed: SELECT Messages.id as msg_id, messages.convo_id, from_dispname, messages.author, messages.timestamp, messages.body_xml, conversations.displayname, Messages.dialog_partner FROM Messages LEFT JOIN Conversations ON messages.convo_id = conversations.id Figure 30 4. Twitter ----- The database files storing the Twitter messages are made accessible to everyone by running the following commands: chmod 0777 /data/data/com.twitter.android chmod 0777 /data/data/com.twitter.android/databases/*.db The following SQL query is executed: SELECT messages._id, messages.type, messages.msg_id, messages.content, messages.created, messages.sender_id, messages.recipient_id, messages.thread, s.name, s.username, r.name, r.username FROM messages JOIN users s ON messages.sender_id = s.user_id JOIN users r ON messages.recipient_id = r.user_id Figure 31 5. Viber The database files storing the Viber messages are made accessible to everyone by running the following commands: chmod 0777 /data/data/com.viber.voip/ chmod 0777 /data/data/com.viber.voip/databases/viber_messages chmod 0777 /data/data/com.viber.voip/databases/viber_messages-journal The agent executes the SQL query displayed in the figure below. ----- Figure 32 6. WhatsApp The database files storing the WhatsApp messages are made accessible to everyone by running the following commands: chmod 0777 /data/data/com.whatsapp chmod 0777 /data/data/com.whatsapp/databases chmod 0777 /data/data/com.whatsapp/shared_prefs chmod 0777 /data/data/com.whatsapp/shared_prefs/com.whatsapp_preferences.xml chmod 0777 /data/data/com.whatsapp/databases/msgstore.db chmod 0777 /data/data/com.whatsapp/databases/wa.db The following SQL queries are executed: select * from messages select timestamp from messages order by _id desc limit 1 ----- Figure 33 ----- Figure 34 7. Gmail The following SQL queries are executed (“/data/data/com.google.android.gm/databases/EmailProvider.db” database): select * from messages select * from Message select _id from messages order by _id desc limit 1 select _id from Message order by _id desc limit 1 ----- Figure 35 ----- Figure 36 8. Android Native Email The database file storing the Android Native emails and attachments is made accessible to everyone by running the following commands: chmod 0777 /data/data/com.android.email chmod 0777 /data/data/com.android.email/databases/EmailProvider.db The following SQL queries are executed: select * from Message where _id = select * from Attachment where _id = ----- Figure 37 ----- Figure 38 9. Android Native Browser The database file storing the user name and password entered in the WebView is made accessible to everyone by running the following commands: chmod 0777 /data/data/com.android.browser chmod 0777 /data/data/com.android.browser/databases chmod 0777 /data/data/com.android.browser/databases/webview.db The following SQL query is executed: select * from password The agent also extracts the bookmarks and history items from Browser.BOOKMARKS_URI and Browser.HISTORY_PROJECTION. ----- Figure 39 ----- Figure 40 Figure 41 10. Default Calendar The agent extracts the Android version string from the “Build.VERSION.RELEASE” property: ----- Figure 42 Depending on the Android version, the calendar’s events can be found at “content://com.android.calendar/events” or “content://calendar/events”, as shown in figure 43: Figure 43 The application extracts the events title, summary, description, and other properties (see figure 44). The calendar entries are added to an XmlSerializer object that has multiple attributes: Figure 44 **Suicide Functionality** 1st method The agent will kill itself if it finds a file called “/sdcard/MemosForNotes” on the device: Figure 45 The malware starts the removal operation by logging the “removeAppalication start” message, as shown in the figure below: ----- Figure 46 The application removes all files that are located in the “/data/local/tmp/ktmu” directory: Figure 47 The SharedPreferences.Editor.clear function is utilized to remove the following preference files containing configuration data: “NetworkPreferences”, “NetworkWindowAddresess”, and “NetworkDataList” (see figure 48). Figure 48 The following commands are run by the malware: export LD_LIBRARY_PATH=/vendor/lib:/system/lib – set the LD_LIBRARY_PATH environment variable ----- mount -o remount,rw /dev/null /system – remount the system directory force-stop com.network.android – stop the malicious application disable com.network.android – disable the malicious application rm /system/app/com.media.sync.apk – remove this file pm uninstall com.network.android – uninstall the malicious application rm /system/ttg – remove the configuration file chmod 0777 /system/csk; rm /system/csk – delete the binary used to run commands with root privileges (“superuser binary”) ----- Figure 49 2nd method The malware will also remove itself if it didn’t communicate with the C2 server in the last 60 days: ----- Figure 50 3rd method The suicide functionality is also used when no subscriber ID is identified (see figure 18). 4th method ----- The Pegasus C2 server can issue a command to the agent in order to remove itself. Pegasus implements 4 main commands that can be executed: dumpCmd, upgradeCmd, camCmd, and emailAttCmd (figure 51). Figure 51 **dumpCmd command** The agent can activate/deactivate some actions depending on the dumpSms, dumpWhatsApp, dumpEmails, dumpContacts, dumpCalander [sic], dumpCall boolean values: ----- Figure 52 The agent extracts the SMS messages sent and received from “content://sms/sent” and “content://sms/inbox”. Every SMS is stored in a new XmlSerializer object, as highlighted below: Figure 53 ----- Figure 54 The malware extracts the Phone call logs from “CallLog.Calls.CONTENT_URI”. Each log is stored in a new XmlSerializer object that contains attributes such as “recordId”, “timestamp”, “type”, “number”, “duration”, “isStart”, and “direction”: Figure 55 Figure 56 ----- The application retrieves the phone contacts from the “ContactsContract.Contacts.CONTENT_VCARD_URI” entry. Every contact is stored in an XmlSerializer object: Figure 57 Figure 58 Figure 59 The agent obtains a list of application processes running on the device via a call to getRunningAppProcesses: Figure 60 ----- This command is also responsible for retrieving the information already described in the “Targeted applications” section. **upgradeCmd command** The process creates a file called “/data/data/com.network.android/upgrade/uglmt.dat” that will store the upgraded application that is downloaded from the C2 server. It computes the MD5 hash of the file and then compares the result with a value that comes with the package: Figure 61 ----- Figure 62 The agent loads uglmt.dat as a dex file using DexClassLoader and then calls the “com.media.provapp.DrivenObjClass.perfU” method with the “/data/data/com.network.android/upgrade/intro.mp3” argument: Figure 63 Figure 64 ----- After successfully upgrading the agent, the following files are deleted by calling the File.delete function: /data/data/com.network.android/upgrade/uglmt.dat /data/data/com.network.android/upgrade/cuvmnr.dat /data/data/com.network.android/upgrade/zero.mp3 /data/data/com.network.android/upgrade/*com.media.sync* Figure 65 **camCmd command** Firstly, the process relies on a binary that should exist on Android called “/system/bin/screencap” in order to take a screenshot of the screen. The result is saved as a PNG image at “/data/data/com.network.android/bqul4.dat”: ----- Figure 66 Secondly, if the above binary doesn’t exist then the malware will use a resource (found in res/raw/ folder) called “take_screen_shot” that will handle the operation. The result is stored at “/data/data/com.network.android/tss64.dat”: ----- Figure 67 In any case, the screenshots’ information will be stored in an XmlSerializer object described below: ----- Figure 68 As we can see in the assembly code of take_screen_shot, the binary captures the Android screen content by reading the “/dev/graphics/fb0” framebuffer that is processed and stored as a PNG image: ----- Figure 69 Figure 70 The captured PNG images are compressed to JPG and saved as “ScreenShot-res.jpg”: ----- Figure 71 The process can take photos with the front/back camera. It calls the getParameters function in order to obtain the current settings for the Camera service and then calls getPreviewFormat: ----- Figure 72 Depending on the front/back camera, the taken photo is saved as “Front-res.jpg” or “Back-res-.jpg” ----- Figure 73 **emailAttCmd command** The application creates a database containing a table called “NetworkData” that stores the email attachments’ name and path, as displayed in figure 74. Figure 74 The command’s purpose is to extract a specific email attachment mentioned by the C2 server: ----- Figure 75 ----- Figure 76 We were surprised to find out that during the initialization routine, the threat actor mentioned the “Pegasus” string in a log message: Figure 77 -----