{
	"id": "0f6e0e2f-7d82-4939-a9a2-30aba16abe6b",
	"created_at": "2026-04-06T00:14:10.539438Z",
	"updated_at": "2026-04-10T03:21:20.779859Z",
	"deleted_at": null,
	"sha1_hash": "692dbe5fc58d95a3eb825fa7211769407f8f4464",
	"title": "A technical analysis of Pegasus for Android – Part 2 – CYBER GEEKS",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 8383175,
	"plain_text": "A technical analysis of Pegasus for Android – Part 2 – CYBER\r\nGEEKS\r\nPublished: 2022-09-27 · Archived: 2026-04-05 17:17:45 UTC\r\nSummary\r\nPegasus is a spyware developed by the NSO group that was repeatedly analyzed by Amnesty International and\r\nCitizenLab. In this article, we dissect the Android version that was initially analyzed by Lookout in this paper, and\r\nwe recommend reading it along with this post. During our research about Pegasus for Android, we’ve found out\r\nthat vendors wrongly attributed some undocumented APK files to Pegasus, as highlighted by a researcher here.\r\nWe’ve splitted the analysis into 3 parts because of the code’s complexity and length. We’ve also tried to keep the\r\nsections name proposed by Lookout whenever it was possible so that anybody could follow the two approaches\r\nmore easily. In this second part, we’re presenting the HTTP communication with the C2 server, the commands\r\nreceived via SMS that were implemented by the spyware, the live audio surveillance functionality, and the\r\nkeylogging activity. You can consult the first part of the Pegasus analysis here.\r\nAnalyst: @GeeksCyber\r\nTechnical analysis\r\nSHA256: ade8bef0ac29fa363fc9afd958af0074478aef650adeb0318517b48bd996d5d5\r\nCommunication Methods\r\n1. HTTP Communication\r\nThe agent constructs the following URL that contains the C2 server, which can be extracted from the initial\r\nconfiguration or a command sent via SMS:\r\nFigure 1\r\nThe malware adds “SessionId1” and “SessionId2” to the HTTP headers:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 1 of 52\n\nFigure 2\r\nFigure 3 reveals the following values:\r\nSessionId1 = f, which is the token stored on the phone\r\nSessionId2 = c, which is the AES key used to encrypt the files exfiltrated to the C2 server\r\nb – AES key that is used to encrypt the SessionId1 and SessionId2 fields\r\na – AES IV that is used during the encryption of the SessionId1 and SessionId2 fields\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 2 of 52\n\nFigure 3\r\nThe implementation of the AES algorithm is displayed in the figure below.\r\nFigure 4\r\nThe template of the HTTP request is displayed in figure 5:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 3 of 52\n\nFigure 5\r\nThe HTTP response should be an XML file containing at least the following fields: “response”, “code”, and\r\n“message”. The application parses the XML response by overriding the startElement, endElement, and characters\r\nmethods:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 4 of 52\n\nFigure 6\r\nThe agent verifies if the XML response contains the following main commands: “dumpCmd”, “upgrade”,\r\n“camCmd”, and “emailAttCmd” (those were described in part 1). In the case of the “upgrade” command, the\r\nthreat actor must specify the URL to download the package from and others parameters (see figure 7).\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 5 of 52\n\nFigure 7\r\nThe implementation of the overriding functions is shown below:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 6 of 52\n\nFigure 8\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 7 of 52\n\nFigure 9\r\nFigure 10\r\n2. SMS/MMS/WAP\r\nAs in the case of the iOS version, the package can receive commands in SMS messages that are disguised as\r\nGoogle authentication codes. It searches for “your google verification code” in the message and extracts the index\r\nof the “s=” parameter:\r\nFigure 11\r\nThe malware computes the MD5 hash of the Token + SMS[0, index+2), which is truncated to 8 bytes and\r\ncompares it with SMS[index+2, final] in order to verify the authenticity of the command:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 8 of 52\n\nFigure 12\r\nThe command structure is “text:[6 digits][Command number]a=[Ack ID]\u0026[Command Arguments]\u0026s=\u003cMessage\r\nSignature\u003e” and the following regular expression is used to parse it: “.*[:]\\d{6}(\\d)[\\n]?(.*)”.\r\nThe following function is utilized to extract the fields from the command and to add it to a commands queue:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 9 of 52\n\nFigure 13\r\nThe agent verifies if the phone is Roaming via a function call to isNetworkRoaming:\r\nFigure 14\r\nIf the device is Roaming and the “romingSetted” config value is disabled (0), the application can’t accept\r\ncommands via HTTP, SMS, and MQTT:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 10 of 52\n\nFigure 15\r\nThe commands received via SMS will be described in the following paragraphs (numbers in range 0-8).\r\nCommand 0\r\nThe first command is “KILL” and can be used to perform self deletion on the phone:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 11 of 52\n\nFigure 16\r\nThe process sets the intent action to “KILL”, retrieves a PendingIntent that will perform a broadcast, and\r\nschedules an alarm, as displayed below.\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 12 of 52\n\nFigure 17\r\nThe application creates a HandlerThread that will perform the necessary operations:\r\nFigure 18\r\nThe getSubscriberId function is used to obtain the unique subscriber ID, and the deletion operation continues. A\r\ndetailed explanation regarding this operation can be found in the 1st part of the Pegasus analysis – Suicide\r\nfunctionality section.\r\nFigure 19\r\nFigure 20\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 13 of 52\n\nCommand 1\r\nThis command is used to send a “Ping” message via SMS or HTTP. Depending on the value received in the\r\nparameters (“0” or “1”), the spyware chooses between the two communication channels:\r\nFigure 21\r\nThe Ack ID received in the command and a counter value will be part of the SMS message that is sent:\r\nFigure 22\r\nThe process logs the phone number to send messages to, the Ack ID, and the counter. It computes the time after\r\nthe last network communication with C2 in seconds:\r\nFigure 23\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 14 of 52\n\nIn the case of HTTP communication, the agent creates a Handler object and calls the postDelayed function with a\r\ndelay of 5 seconds:\r\nFigure 24\r\nThe malware creates an XmlSerializer object that will be encrypted using the AES algorithm and then sent to a C2\r\nserver via HTTP. Finally, it checks if the data was successfully sent:\r\nFigure 25\r\nCommand 2\r\nIn this case, the process tries to compute the index of “\u0026” in the arguments. The resulting two values will be used\r\nto modify the “adrate” and “adlocation” configuration options:\r\nFigure 26\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 15 of 52\n\nFor example, if the “adrate” value is set to 0 then the malware stops the location monitoring functionality.\r\nHowever, if the “adlocation” value is 0 or “adrate” \u003c “adlocation” then the malware starts the functionality:\r\nFigure 27\r\nWhen stopping the location monitoring functionality, the process  sets the intent action to\r\n“finishLocationMonitor” and calls the cancel method:\r\nFigure 28\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 16 of 52\n\nThe getSystemService function is utilized to retrieve a handle to the location service. The agent receives data\r\nabout the location from the network and passive providers (see figure 29).\r\nFigure 29\r\nCommand 3\r\nThe process configures the following config options:\r\n“WindowTargetSms” – SMS number used in the outbound communication\r\n“Skypi” – Phone number used to trigger the live audio surveillance functionality\r\n“NetworkWindowAddresess”\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 17 of 52\n\nFigure 30\r\nThe entire list of config options that can be set using this command is presented at the end of the Lookout’s paper.\r\nCommand 4\r\nThe application obtains the index of “\u0026” in the arguments and creates two values representing the camera\r\nsnapshot number and time, as shown in figure 31.\r\nFigure 31\r\nThe snapshot source type and the phone camera resolution are logged using the Log.i method:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 18 of 52\n\nFigure 32\r\nThe agent tries to take a snapshot of the screen using a binary called “/system/bin/screencap”. The photo is saved\r\nat “/data/data/com.network.android/bqul4.dat”. A deep dive into the screenshot functionality can be found in the\r\n1st part of the Pegasus analysis.\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 19 of 52\n\nFigure 33\r\nCommand 5\r\nIn this case, the malware specifies a file or a directory listing to be exfiltrated. This information can be transmitted\r\nin the “f=” and “p=” parameters:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 20 of 52\n\nFigure 34\r\nThe process changes permissions to 777 for the targeted file using the “superuser binary”. It verifies the existence\r\nof the file by calling the File.exists method and expects a non-empty file:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 21 of 52\n\nFigure 35\r\nThe application creates a directory called “/data/data/com.network.android/chnkr/” using the File.mkdirs function.\r\nThe targeted file is copied to the newly created folder, and the malware broadcasts the “new_chunker_file_event”\r\nintent to all BroadcastReceivers in order to exfiltrate data:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 22 of 52\n\nFigure 36\r\nCommand 6\r\nThis command prepares the phone to accept an audio surveillance call that will be detailed in the “Live Audio\r\nSurveillance” section.\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 23 of 52\n\nFigure 37\r\nCommand 7\r\nThe package enables the call recording functionality by setting the “window canada” config value to true:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 24 of 52\n\nFigure 38\r\nCommand 8\r\nThe agent extracts the configured C2 servers and sends a request to one of them in order to ask for new\r\ncommands, as shown in the figure below.\r\nFigure 39\r\nIt sets the intent action to “httpPing”, the intent data to “PING: \u003cCurrent time in milliseconds\u003e”, retrieves a\r\nPendingIntent that will perform a broadcast, and schedules an alarm:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 25 of 52\n\nFigure 40\r\nFigure 41\r\nOutbound SMS\r\nThe malware logs the message “MO sendSmsMO Ping SMS MO Start to number: ” + WindowTargetSms, which\r\nis the phone number used in the outbound communication:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 26 of 52\n\nFigure 42\r\nThe agent extracts the following information: the current location of the device, the numeric name (MCC+MNC)\r\nof the registered operator, the GSM cell ID, the GSM location area code, the IMEI and IMSI of the device (see\r\nfigure 43).\r\nFigure 43\r\nThe application obtains the unique subscriber ID that is validated based on its length:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 27 of 52\n\nFigure 44\r\nSmsManager.getDefault is utilized to retrieve the SmsManager. The process creates two Intents with the\r\n“SMS_SENT” and “SMS_DELIVERED” parameters and then broadcasts them via a call to getBroadcast. Finally,\r\nthe SMS containing the information extracted above is sent using sentTextMessage:\r\nFigure 45\r\nThe getResultCode method is used to verify if the message was successfully sent. If that’s not the case, the SMS is\r\nre-sent in 1 minute:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 28 of 52\n\nFigure 46\r\nThe application logs the number of times it re-sent the SMS using the Log.i method:\r\nFigure 47\r\nLive Audio Surveillance\r\nThe threat actor can enable this functionality only when multiple conditions are met at the same time. The\r\nfunctionality can be activated when the phone receives a call from the attacker’s number, and it will allow\r\ncapturing the audio via the device’s microphone.\r\nThe first condition to be met is that the phone’s screen is OFF, which is verified using a variable that should be\r\nfalse. The malware verifies if the screen is ON or OFF by calling the isScreenOn method. The configuration\r\noption called “Skypi” should be not null:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 29 of 52\n\nFigure 48\r\nFigure 49\r\nFigure 50\r\nThe process makes sure that the user didn’t cancel the previous live surveillance operation, as displayed in the\r\nfigure below.\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 30 of 52\n\nFigure 51\r\nThe phone should be in the idle state, and the phone’s screen should be locked. The\r\ninKeyguardRestrictedInputMode function is used to verify the last condition:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 31 of 52\n\nFigure 52\r\nFigure 53\r\nFigure 54\r\nThe configuration option called “forwarding” indicates whether call forwarding is enabled on the phone. This\r\nfeature should be disabled for the functionality to work:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 32 of 52\n\nFigure 55\r\nFigure 56\r\nThe agent extracts the value of the “STAY_ON_WHILE_PLUGGED_IN” constant. It expects the device to stay\r\noff even if it’s charging:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 33 of 52\n\nFigure 57\r\nThe microphone should not be in use for the functionality to work:\r\nFigure 58\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 34 of 52\n\nFigure 59\r\nisWiredHeadsetOn is utilized to confirm that a wired headset is not connected to the phone:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 35 of 52\n\nFigure 60\r\nisBluetoothA2dpOn is utilized to confirm that a Bluetooth A2DP audio peripheral is not connected to the phone:\r\nFigure 61\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 36 of 52\n\nThe spyware doesn’t expect communications to use Bluetooth SCO at the time of the audio surveillance. It calls\r\nthe isBluetoothScoOn method for this purpose:\r\nFigure 62\r\nThe music should not be active during the time of the operation, as highlighted below:\r\nFigure 63\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 37 of 52\n\nThe final condition that must be met is that either the phone is not Roaming or the functionality was configured by\r\nthe TA to be performed even if the device is Roaming:\r\nFigure 64\r\nFigure 65\r\nNow we’ll describe the functionality after all of the above conditions are met.\r\nAudio recording\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 38 of 52\n\nThe application creates a MediaRecorder object that can be used to record audio and video:\r\nFigure 66\r\nThe agent sets the audio mode to 2 (MODE_IN_CALL – a call is established), calls the setStreamSolo function\r\nwith a True parameter, sets the audio source to be used depending on the phone’s build model, sets the format of\r\nthe output file to 2 (MPEG4 media file format), and sets the audio encoder to 1 (AMR_NB – narrowband audio\r\ncodec):\r\nFigure 67\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 39 of 52\n\nFigure 68\r\nThe directory “/data/data/com.network.android/network_cache/” is created by the spyware:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 40 of 52\n\nFigure 69\r\nThe output file is “/data/data/com.network.android/network_cache/cache1.dat\u003cInteger\u003e”, and the recording is\r\nstarted by calling the prepare and start functions:\r\nFigure 70\r\nThe audio files can be exfiltrated by incorporating them into XML files, as displayed in the figure below.\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 41 of 52\n\nFigure 71\r\nPhone Calls\r\nThe following columns can be extracted from the Call logs: “number”, “type”, “date”, “duration”, “_id”, and\r\n“logtype” (see figure 72).\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 42 of 52\n\nFigure 72\r\nThe agent implements a different functionality for calls coming from these two numbers: “*762646466” and\r\n“*7626464633”. If the phone receives a call from the first number/second number, then the “romingSetted”\r\nconfiguration option is set to true/false. This option controls how the phone communicates with the C2 server (via\r\nSMS, HTTP, MQTT) when it’s Roaming:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 43 of 52\n\nFigure 73\r\nFigure 74\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 44 of 52\n\nKeylogging\r\nAs we’ve already seen, the spyware logs relevant messages regarding the activities performed:\r\nFigure 75\r\nThe malware expects to find the “superuser binary” called “/system/csk” on the device:\r\nFigure 76\r\nThe files containing the keystrokes will be stored in the “/data/local/tmp/ktmu” folder. The content of these files\r\nwill be exfiltrated using XmlSerializer objects with specific tags:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 45 of 52\n\nFigure 77\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 46 of 52\n\nFigure 78\r\nThe application tries to identify the process ID of the keyboard process:\r\nFigure 79\r\nIt extracts the process ID for the input method service that is currently selected from the “default_input_method”\r\nvalue. The getRunningAppProcesses function is utilized to obtain a list of running processes on the phone, and\r\nthen the spyware extracts the process ID and name of the keyboard process:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 47 of 52\n\nFigure 80\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 48 of 52\n\nFigure 81\r\nThe libk binary found in the “/res/raw” directory is copied to a new file called “/data/local/tmp/libuml.so”. The\r\nshared object is injected (using the addk binary) in the keyboard process identified above and will be responsible\r\nfor the keylogging activity:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 49 of 52\n\nFigure 82\r\nThe captured keystrokes will be stored in a file called “/data/local/tmp/ktmu/ulmndd.tmp”, as shown in figure 83.\r\nFigure 83\r\nThe agent stores the bitwise NOT of every keystroke in the file using the fwrite instruction:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 50 of 52\n\nFigure 84\r\nThe temporary file storing the captured keystrokes is renamed as “/data/local/tmp/ktmu/finidk.\u003ccurrent\r\ntimestamp\u003e”. The current timestamp is obtained using the time syscall:\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 51 of 52\n\nFigure 85\r\nSource: https://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nhttps://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/\r\nPage 52 of 52\n\n https://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/   \nFigure 51    \nThe phone should be in the idle state, and the phone’s screen should be locked. The\ninKeyguardRestrictedInputMode function is used to verify the last condition:\n   Page 31 of 52 \n\n  https://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/ \nFigure 84   \nThe temporary file storing the captured keystrokes is renamed as “/data/local/tmp/ktmu/finidk.\u003ccurrent\ntimestamp\u003e”. The current timestamp is obtained using the time syscall:\n   Page 51 of 52",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://cybergeeks.tech/a-technical-analysis-of-pegasus-for-android-part-2/"
	],
	"report_names": [
		"a-technical-analysis-of-pegasus-for-android-part-2"
	],
	"threat_actors": [],
	"ts_created_at": 1775434450,
	"ts_updated_at": 1775791280,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/692dbe5fc58d95a3eb825fa7211769407f8f4464.pdf",
		"text": "https://archive.orkl.eu/692dbe5fc58d95a3eb825fa7211769407f8f4464.txt",
		"img": "https://archive.orkl.eu/692dbe5fc58d95a3eb825fa7211769407f8f4464.jpg"
	}
}