A technical analysis of Pegasus for Android – Part 2

Summary

Pegasus is a spyware developed by the NSO group that was repeatedly analyzed by Amnesty International and CitizenLab. In this article, we dissect the Android version that was initially analyzed by Lookout in this paper, and we recommend reading it along with this post. 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. 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 second part, we’re presenting the HTTP communication with the C2 server, the commands received via SMS that were implemented by the spyware, the live audio surveillance functionality, and the keylogging activity. You can consult the first part of the Pegasus analysis here.

Analyst@GeeksCyber

Technical analysis

SHA256: ade8bef0ac29fa363fc9afd958af0074478aef650adeb0318517b48bd996d5d5

Communication Methods

1. HTTP Communication

The agent constructs the following URL that contains the C2 server, which can be extracted from the initial configuration or a command sent via SMS:

Figure 1

The malware adds “SessionId1” and “SessionId2” to the HTTP headers:

Figure 2

Figure 3 reveals the following values:

  • SessionId1 = f, which is the token stored on the phone
  • SessionId2 = c, which is the AES key used to encrypt the files exfiltrated to the C2 server
  • b – AES key that is used to encrypt the SessionId1 and SessionId2 fields
  • a – AES IV that is used during the encryption of the SessionId1 and SessionId2 fields
Figure 3

The implementation of the AES algorithm is displayed in the figure below.

Figure 4

The template of the HTTP request is displayed in figure 5:

Figure 5

The HTTP response should be an XML file containing at least the following fields: “response”, “code”, and “message”. The application parses the XML response by overriding the startElement, endElement, and characters methods:

Figure 6

The agent verifies if the XML response contains the following main commands: “dumpCmd”, “upgrade”, “camCmd”, and “emailAttCmd” (those were described in part 1). In the case of the “upgrade” command, the threat actor must specify the URL to download the package from and others parameters (see figure 7).

Figure 7

The implementation of the overriding functions is shown below:

Figure 8
Figure 9
Figure 10

2. SMS/MMS/WAP

As in the case of the iOS version, the package can receive commands in SMS messages that are disguised as Google authentication codes. It searches for “your google verification code” in the message and extracts the index of the “s=” parameter:

Figure 11

The malware computes the MD5 hash of the Token + SMS[0, index+2), which is truncated to 8 bytes and compares it with SMS[index+2, final] in order to verify the authenticity of the command:

Figure 12

The command structure is “text:[6 digits][Command number]a=[Ack ID]&[Command Arguments]&s=<Message Signature>” and the following regular expression is used to parse it: “.*[:]\d{6}(\d)[\n]?(.*)”.

The following function is utilized to extract the fields from the command and to add it to a commands queue:

Figure 13

The agent verifies if the phone is Roaming via a function call to isNetworkRoaming:

Figure 14

If the device is Roaming and the “romingSetted” config value is disabled (0), the application can’t accept commands via HTTP, SMS, and MQTT:

Figure 15

The commands received via SMS will be described in the following paragraphs (numbers in range 0-8).

Command 0

The first command is “KILL” and can be used to perform self deletion on the phone:

Figure 16

The process sets the intent action to “KILL”, retrieves a PendingIntent that will perform a broadcast, and schedules an alarm, as displayed below.

Figure 17

The application creates a HandlerThread that will perform the necessary operations:

Figure 18

The getSubscriberId function is used to obtain the unique subscriber ID, and the deletion operation continues. A detailed explanation regarding this operation can be found in the 1st part of the Pegasus analysis – Suicide functionality section.

Figure 19
Figure 20

Command 1

This command is used to send a “Ping” message via SMS or HTTP. Depending on the value received in the parameters (“0” or “1”), the spyware chooses between the two communication channels:

Figure 21

The Ack ID received in the command and a counter value will be part of the SMS message that is sent:

Figure 22

The process logs the phone number to send messages to, the Ack ID, and the counter. It computes the time after the last network communication with C2 in seconds:

Figure 23

In the case of HTTP communication, the agent creates a Handler object and calls the postDelayed function with a delay of 5 seconds:

Figure 24

The malware creates an XmlSerializer object that will be encrypted using the AES algorithm and then sent to a C2 server via HTTP. Finally, it checks if the data was successfully sent:

Figure 25

Command 2

In this case, the process tries to compute the index of “&” in the arguments. The resulting two values will be used to modify the “adrate” and “adlocation” configuration options:

Figure 26

For example, if the “adrate” value is set to 0 then the malware stops the location monitoring functionality. However, if the “adlocation” value is 0 or “adrate” < “adlocation” then the malware starts the functionality:

Figure 27

When stopping the location monitoring functionality, the process  sets the intent action to “finishLocationMonitor” and calls the cancel method:

Figure 28

The getSystemService function is utilized to retrieve a handle to the location service. The agent receives data about the location from the network and passive providers (see figure 29).

Figure 29

Command 3

The process configures the following config options:

  • “WindowTargetSms” – SMS number used in the outbound communication
  • “Skypi” – Phone number used to trigger the live audio surveillance functionality
  • “NetworkWindowAddresess”
Figure 30

The entire list of config options that can be set using this command is presented at the end of the Lookout’s paper.

Command 4

The application obtains the index of “&” in the arguments and creates two values representing the camera snapshot number and time, as shown in figure 31.

Figure 31

The snapshot source type and the phone camera resolution are logged using the Log.i method:

Figure 32

The agent tries to take a snapshot of the screen using a binary called “/system/bin/screencap”. The photo is saved at “/data/data/com.network.android/bqul4.dat”. A deep dive into the screenshot functionality can be found in the 1st part of the Pegasus analysis.

Figure 33

Command 5

In this case, the malware specifies a file or a directory listing to be exfiltrated. This information can be transmitted in the “f=” and “p=” parameters:

Figure 34

The process changes permissions to 777 for the targeted file using the “superuser binary”. It verifies the existence of the file by calling the File.exists method and expects a non-empty file:

Figure 35

The application creates a directory called “/data/data/com.network.android/chnkr/” using the File.mkdirs function. The targeted file is copied to the newly created folder, and the malware broadcasts the “new_chunker_file_event” intent to all BroadcastReceivers in order to exfiltrate data:

Figure 36

Command 6

This command prepares the phone to accept an audio surveillance call that will be detailed in the “Live Audio Surveillance” section.

Figure 37

Command 7

The package enables the call recording functionality by setting the “window canada” config value to true:

Figure 38

Command 8

The agent extracts the configured C2 servers and sends a request to one of them in order to ask for new commands, as shown in the figure below.

Figure 39

It sets the intent action to “httpPing”, the intent data to “PING: <Current time in milliseconds>”, retrieves a PendingIntent that will perform a broadcast, and schedules an alarm:

Figure 40
Figure 41

Outbound SMS

The malware logs the message “MO sendSmsMO Ping SMS MO Start to number: ” + WindowTargetSms, which is the phone number used in the outbound communication:

Figure 42

The agent extracts the following information: the current location of the device, the numeric name (MCC+MNC) of the registered operator, the GSM cell ID, the GSM location area code, the IMEI and IMSI of the device (see figure 43).

Figure 43

The application obtains the unique subscriber ID that is validated based on its length:

Figure 44

SmsManager.getDefault is utilized to retrieve the SmsManager. The process creates two Intents with the “SMS_SENT” and “SMS_DELIVERED” parameters and then broadcasts them via a call to getBroadcast. Finally, the SMS containing the information extracted above is sent using sentTextMessage:

Figure 45

The getResultCode method is used to verify if the message was successfully sent. If that’s not the case, the SMS is re-sent in 1 minute:

Figure 46

The application logs the number of times it re-sent the SMS using the Log.i method:

Figure 47

Live Audio Surveillance

The threat actor can enable this functionality only when multiple conditions are met at the same time. The functionality can be activated when the phone receives a call from the attacker’s number, and it will allow capturing the audio via the device’s microphone.

The first condition to be met is that the phone’s screen is OFF, which is verified using a variable that should be false. The malware verifies if the screen is ON or OFF by calling the isScreenOn method. The configuration option called “Skypi” should be not null:

Figure 48
Figure 49
Figure 50

The process makes sure that the user didn’t cancel the previous live surveillance operation, as displayed in the figure below.

Figure 51

The phone should be in the idle state, and the phone’s screen should be locked. The inKeyguardRestrictedInputMode function is used to verify the last condition:

Figure 52
Figure 53
Figure 54

The configuration option called “forwarding” indicates whether call forwarding is enabled on the phone. This feature should be disabled for the functionality to work:

Figure 55
Figure 56

The agent extracts the value of the “STAY_ON_WHILE_PLUGGED_IN” constant. It expects the device to stay off even if it’s charging:

Figure 57

The microphone should not be in use for the functionality to work:

Figure 58
Figure 59

isWiredHeadsetOn is utilized to confirm that a wired headset is not connected to the phone:

Figure 60

isBluetoothA2dpOn is utilized to confirm that a Bluetooth A2DP audio peripheral is not connected to the phone:

Figure 61

The spyware doesn’t expect communications to use Bluetooth SCO at the time of the audio surveillance. It calls the isBluetoothScoOn method for this purpose:

Figure 62

The music should not be active during the time of the operation, as highlighted below:

Figure 63

The final condition that must be met is that either the phone is not Roaming or the functionality was configured by the TA to be performed even if the device is Roaming:

Figure 64
Figure 65

Now we’ll describe the functionality after all of the above conditions are met.

Audio recording

The application creates a MediaRecorder object that can be used to record audio and video:

Figure 66

The agent sets the audio mode to 2 (MODE_IN_CALL – a call is established), calls the setStreamSolo function with a True parameter, sets the audio source to be used depending on the phone’s build model, sets the format of the output file to 2 (MPEG4 media file format), and sets the audio encoder to 1 (AMR_NB – narrowband audio codec):

Figure 67
Figure 68

The directory “/data/data/com.network.android/network_cache/” is created by the spyware:

Figure 69

The output file is “/data/data/com.network.android/network_cache/cache1.dat<Integer>”, and the recording is started by calling the prepare and start functions:

Figure 70

The audio files can be exfiltrated by incorporating them into XML files, as displayed in the figure below.

Figure 71

Phone Calls

The following columns can be extracted from the Call logs: “number”, “type”, “date”, “duration”, “_id”, and “logtype” (see figure 72).

Figure 72

The agent implements a different functionality for calls coming from these two numbers: “*762646466” and “*7626464633”. If the phone receives a call from the first number/second number, then the “romingSetted” configuration option is set to true/false. This option controls how the phone communicates with the C2 server (via SMS, HTTP, MQTT) when it’s Roaming:

Figure 73
Figure 74

Keylogging

As we’ve already seen, the spyware logs relevant messages regarding the activities performed:

Figure 75

The malware expects to find the “superuser binary” called “/system/csk” on the device:

Figure 76

The files containing the keystrokes will be stored in the “/data/local/tmp/ktmu” folder. The content of these files will be exfiltrated using XmlSerializer objects with specific tags:

Figure 77
Figure 78

The application tries to identify the process ID of the keyboard process:

Figure 79

It extracts the process ID for the input method service that is currently selected from the “default_input_method” value. The getRunningAppProcesses function is utilized to obtain a list of running processes on the phone, and then the spyware extracts the process ID and name of the keyboard process:

Figure 80
Figure 81

The libk binary found in the “/res/raw” directory is copied to a new file called “/data/local/tmp/libuml.so”. The shared object is injected (using the addk binary) in the keyboard process identified above and will be responsible for the keylogging activity:

Figure 82

The captured keystrokes will be stored in a file called “/data/local/tmp/ktmu/ulmndd.tmp”, as shown in figure 83.

Figure 83

The agent stores the bitwise NOT of every keystroke in the file using the fwrite instruction:

Figure 84

The temporary file storing the captured keystrokes is renamed as “/data/local/tmp/ktmu/finidk.<current timestamp>”. The current timestamp is obtained using the time syscall:

Figure 85

4.3 7 votes
Article Rating
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
UserNotFound

Great content.