Scanning My Own iPhone for Pegasus
10/24/20267 min read


Scanning My Own iPhone for Pegasus
I connected my phone to a Mac and ran Amnesty International's Mobile Verification Toolkit against 22,988 spyware indicators. Here is what the tool actually does, what it found, and — more importantly — what a clean result does not prove.
A 131 GB encrypted backup · 464,282 records · 19 indicator sets · 28 analysis modules
Verdict
No known spyware indicators found. Zero CRITICAL, HIGH, LOW, or INFORMATIONAL alerts. A single MEDIUM alert turned out to be my own app, installed through TestFlight.
MVT prints its own caveat at the end of every run, and it is worth repeating: the lack of severe alerts does not equate to a clean bill of health.
The thing most people get wrong about MVT
MVT is not an antivirus. It does not run on your phone, watch processes, or sniff packets. It is a retrospective forensic tool: it reads a backup, a sysdiagnose archive, or a full filesystem dump, and compares what it finds against published indicators of compromise.
That sounds like a weakness until you realise what is inside an iOS backup. It is not just photos and contacts — it contains iOS's own historical logs, and that is where the evidence lives:
DataUsage.sqlite — a per-process network usage ledger going back years
IDStatusCache — which Apple IDs performed lookups against the device
WebKit resource-load statistics and Safari history — exploit delivery domains
Configuration profiles, TCC permissions, Shortcuts, crash and analytics logs
Pegasus has historically been caught precisely here: anomalous process names appearing in DataUsage, and one-click exploit domains in WebKit caches.
The one setting you have to change
iOS deliberately withholds its sensitive data classes — keychain, Health, Safari history, call history, and DataUsage.sqlite — from unencrypted local backups. You must enable backup encryption to get them. This is a local-backup setting only; it does not touch iCloud Backup or your Apple ID.
An unencrypted backup scan is close to worthless for this purpose. If you skip this step, a clean result means nothing.
The pipeline
Five stages, in order. The numbering is real — each step depends on the one before it.
01
Pair and enable encryption
idevicebackup2 encryption on — the device prompts for its passcode. Nothing is installed; no jailbreak.
02
Full local backup
idevicebackup2 backup --full — 131 GB, 181,190 files, roughly an hour over USB.
03
Decrypt
mvt-ios decrypt-backup — writes a second, plaintext copy. This is the riskiest moment of the whole exercise (see below).
04
Match
mvt-ios check-backup — 28 modules, 19 STIX2 indicator bundles, 22,988 unique indicators.
05
Triage, then destroy
Read every *_detected.json. Then delete the plaintext copy and revoke the pairing record.
What it checked
Twenty-eight modules ran. Grouped by what each can actually prove:
ModuleWhat it can proveDatausage, OSAnalyticsADDailyPer-process network usage over months. The highest-value artifact — where Pegasus process names surface.IDStatusCacheApple IDs that performed lookups against the device. A known zero-click reconnaissance footprint.SafariHistory, WebkitResourceLoadStatistics, WebkitSessionResourceLog, SafariBrowserStateVisits to known exploit-delivery domains — the "one-click" vector.SMS, SMSAttachmentsExploit links delivered over iMessage or SMS.ConfigurationProfiles, ProfileEventsRogue MDM or configuration profiles.TCCWhat was granted microphone, camera, and location access.LocationdClientsProcesses that requested location.ShortcutsPersistence via automations.ManifestPath-based matching across every file in the backup.ApplicationsInstalled apps against the stalkerware corpus, plus a sideloading heuristic.Calls, Contacts, InteractionC, BackupInfo, WhatsappContactsExtraction only — these five do not support indicator matching.Calendar, Whatsapp, ChromeHistory, ChromeFavicon, FirefoxHistory, FirefoxFavicon, GlobalPreferencesSupporting context and cross-referencing.
The indicator sets
MVT pulls STIX2 bundles from three GitHub organisations: mvt-project, AmnestyTech, and AssoEchap. Nineteen bundles, 22,988 unique indicators once expanded.
I have only attributed a vendor or country where the bundle metadata or the published research actually says so. Several ship with no attribution at all, and I have left those blank rather than guess — a distinction most writeups quietly skip.
FamilyDatedIndicatorsAttributionPlatformPegasus2021-07-181,549NSO Group (Israel)iOSPredator—583Intellexa / CytroxiOS, AndroidCandiru (DevilsTongue)—125Candiru (Israel)Cross-platformKingsPawn / Reign2023-04-11167QuaDream (Israel)iOSRCS Lab (Hermit)2022-06-2340RCS Lab (Italy)iOS, AndroidWintego Helios2024-05-02175Wintego (Israel)Cross-platformOperation Triangulation2023-06-01112Documented by Kaspersky; attribution unresolvediOSCoruna / PLASMAGRID2026-03-03215UNC6353, UNC6691 — targets crypto wallet appsiOSDarkSword2026-03-3043Exploit chain; documented by GTIG, iVerify, LookoutiOSSpyrtacus2026-04-099Bundle path attributes to SIO (Italy)—Morpheus2026-04-238none in bundle—BTMOB2026-05-26162none in bundle — the newest set—ResidentBat—48none in bundle—Cellebrite—1Forensic extraction vendor (Israel), not spyware—NoviSpy2024-12-1618Serbian state use (Amnesty)AndroidEagleMsgSpy2024-12-2551Chinese public security (Lookout)AndroidWyrmSpy / DragonEgg2023-07-2553APT41 (Lookout)AndroidMercenary campaign2023-03-292,187Amnesty — mercenary spyware campaignAndroidStalkerware corpusrolling6,086TheTruthSpy, HelloSpy, SpyAdvice, Reptilicus, PhoneSheriff and othersMostly Android
An honest asymmetry
Roughly 8,400 of those indicators target Android. On an iPhone they can never match. The effective iOS-relevant corpus is far smaller than the headline number — which is why "22,988 indicators checked" is a less impressive statistic than it sounds.
What the scan actually parsed
464,282records analysed
8,652DataUsage rows
3,307distinct processes
8,266WebKit entries
257,776manifest files
1MEDIUM alert
ArtifactRecordsArtifactRecordsmanifest257,776calls2,965whatsapp151,659calendar583interaction_c13,372os_analytics_ad_daily491sms13,321contacts318datausage8,652locationd_clients304webkit_resource_load_statistics8,266tcc246urls6,113applications107safari_history60shortcuts13
The findings
01 The one alert was my own app
{
"level": "MEDIUM",
"module": "applications",
"message": "Suspicious app not installed from the App Store or MDM: com.khalifa.kalorie",
"event": {
"itemName": "Kalorie - AI Nutrition Tracker",
"sourceApp": "com.apple.TestFlight",
"distributorInfo": { "localizedDistributorName": "TestFlight", "betaTesterType": 1 },
"genre": "Health & Fitness"
},
"matched_indicator": null
}
This is an app I wrote, running through TestFlight. The applications module flags anything not delivered by the App Store or MDM, and TestFlight — though an official Apple channel — is neither.
The decisive field is the last one. matched_indicator: null means it matched no spyware indicator whatsoever. It is a heuristic flag, not an IOC hit. Anyone reading *_detected.json files should check that field before panicking.
02 A configuration profile that looks alarming and isn't
One configuration profile was present, installed 30 December 2025, with null name and UUID in MVT's summary — which looks exactly like something you would want to investigate. The raw plist resolves it immediately:
"PayloadType": "com.apple.wifi.managed"
"SSID_STR": "du Mobile Offload"
"carrierName": "du"
"isInstalledInteractively": false
"MCProfileIsRemovalStub": true
A carrier Wi-Fi offload profile from du, the UAE operator, consistent with the device's GMT+4 timezone — and it is a removal stub, the residue of an already-uninstalled profile. Benign. Rogue MDM profiles are a genuine attack vector, so this is worth checking, but this one is routine carrier configuration.
03 DataUsage was clean, and I checked it twice
8,652 rows across 3,307 distinct process names. I did not take MVT's word for it; I ran an independent regex for historically documented Pegasus process names (bh, msgacntd, roleaboutd, fmld, pcsd, rolexd and others) directly against the parsed output.
My check produced two "hits" in DataUsage and five in the manifest. All seven were false positives of my own over-broad pattern — the genuine Apple nehelper daemon, Apple's com.apple.aggregated analytics plists, and, memorably, npm node_modules TypeScript files sitting in iCloud Drive. My pattern should have been aggregatedictionaryd, not aggregated.
Worth stating plainly because it cuts both ways: a sloppy indicator will manufacture evidence. The discipline of reading each hit rather than counting them is the entire job.
04 The actually actionable finding
Patch gap
MVT raised this, and it is the most useful thing the scan produced: the device was running iOS 26.6.1 when 27.0.1 was current — a full major version behind.
Every commercial exploit chain in the table above depends on an unpatched vulnerability. A clean indicator scan on an out-of-date device is a weaker result than a clean scan on a current one, because the window for the next chain is wide open.
What this does not prove
This is the section most writeups omit, and it is the one that matters.
Indicators are retrospective by definition. MVT matches what researchers have already published. A current, undocumented chain leaves no indicator to match.
Modern implants are largely memory-resident. Pegasus in particular leaves little on disk and its operators can clean up behind themselves. Amnesty's own reporting describes traces being wiped.
The device generated its own evidence. MVT analyses a backup produced by the phone under investigation. An implant with kernel-level access could in principle filter what enters that backup. A clean result means clean according to the suspect.
Five modules cannot match indicators at all. Calls, Contacts, InteractionC, BackupInfo, and WhatsappContacts extract data but perform no IOC comparison.
One named gap in this run. WhatsApp's ContactsV2.sqlite was absent from the backup, so disappearing-message settings and WhatsApp contact records were never examined.
Most of the corpus is Android. See the asymmetry note above.
A stronger signal than any local scan
Apple proactively notifies users it assesses were targeted by mercenary spyware — by email and iMessage to the Apple ID, plus a banner at appleid.apple.com. If you have never received one, that is independent corroboration carrying more weight than a clean MVT run, because it reflects Apple's server-side telemetry rather than artifacts on a device that may itself be compromised.
Auditing the tools, not just the phone
It is worth asking whether the toolchain you point at your own device is trustworthy. There is no single Git repo here — three distinct supply chains, with different properties:
ComponentSourceVerificationmvt 2026.10.12PyPI, installed via uv167 files SHA-256 pinned in RECORD; all 20 dependencies == pinned19 IOC bundlesraw.githubusercontent.comTLS only — no signatureslibimobiledevice 1.4.0Homebrew bottleSHA-256 verified by brew
Provenance signals that do check out: the package author email is nex@nex.sx — Claudio Guarnieri, who actually leads Amnesty International's Security Lab — and the repository URL is the official github.com/mvt-project/mvt. Consistent with the real project rather than a typosquat.
One thing worth verifying before you run it: MVT contains a VirusTotal code path. It is opt-in and inert — it returns early unless an API key is configured, and it is gated behind an explicit flag. Even when enabled it transmits file hashes, never file contents.
What I did not verify, stated plainly: no signature or PyPI attestation check on the wheel. Hash-pinning proves the wheel was not altered after download; it does not prove the wheel on PyPI is the one Amnesty built. And the IOC bundles carry no signatures — trust rests on TLS plus GitHub account integrity. The blast radius is bounded, since they are parsed as data rather than executed, but a tampered set could be crafted to suppress a real detection.
The real risk is the one you create
The decrypt step writes a second, plaintext copy of the entire phone — keychain, every message, Safari history, call logs, photos. In this case roughly 130 GB in the clear in a home directory.
FileVault protects it at rest, but any process running as your user can read it while you are logged in. This exposure exists purely to run the scan, so treat it as a short-lived operation: scan, triage, then delete the plaintext copy. Pairing also creates a lockdown record granting that Mac ongoing trusted access to the device — revoke it when you are done.
If you run this yourself
Encrypt the backup. Non-negotiable. An unencrypted scan cannot see the artifacts that matter.
Budget the disk. You need room for the backup and a full plaintext copy — roughly twice the phone's used space. Mine wanted about 260 GB.
Trust AmountDataAvailable, not TotalDataAvailable. I sized this run from the latter and was wrong by a factor of nearly three.
Read every detection, and check matched_indicator. A null value means a heuristic fired, not an indicator.
Beware pgrep -f. My own progress monitor matched its own command line and would never have fired. Match on the binary name instead.
Update iOS first. It is worth more than the scan.
Consider Lockdown Mode. If you have plausible reason to think you are a target, it closes most of the attack surface these chains rely on.
Delete the plaintext copy and unpair when you are finished.
Resources
Support
khalifa@kenaid.io
© 2025. All rights reserved.