MacSecLabs
00.1Free preview

00.1 Course introduction: the iOS application pentest

Phase 00 · Module 1 of 7 · Free preview

An iOS application pentest is not a string dump followed by a Frida script. It is a chain of decisions: define what the IPA is allowed to do, map the bundle before changing the runtime, reproduce each weakness, separate lab-only access from stock-device impact, and write a finding that survives technical review.

This course puts you inside that workflow with one authorized target and an instrumented iOS 26.1 research guest. MediVault (com.macseclabs.medivault) is a MacSec-owned clinical-records training app built for the assessment. You will inventory its IPA, instrument the process with Frida 17, intercept traffic in Burp, recover planted patient records from storage and IPC, test authentication and cryptography, map its runtime protections, patch the binary when a hook is not enough, and turn the evidence into findings a client can reproduce and fix.

The lab gives you privileged research access. The report does not get privileged assumptions. Every finding is classified as jailbreak-required, modified-IPA, or stock-claimable so the technical proof and the customer impact never drift apart.

Finish the phases in order and you will have a repeatable assessment workflow, an attack-surface map, a runtime and data evidence set, and a complete report. You should be able to apply the same sequence to the next authorized IPA without depending on an instructor or overstating what the evidence proves.

This page maps that journey and establishes the lab identity. Rules of engagement, in-scope wording, and evidence retention begin in 01.1.

What you will produce

This is a working assessment, not a collection of disconnected tool demonstrations.

DeliverableWhat it demonstrates
Engagement and evidence planYou can define scope, authorization, stopping conditions, and the claim each artifact must support.
IPA attack-surface mapYou can turn bundle metadata, entitlements, strings, SDKs, endpoints, and native code into a ranked test plan.
Network and runtime evidenceYou can reproduce pinning, authentication, IPC, storage, cryptography, and runtime-protection behavior without relying on tool output alone.
Finding set with claim rungsYou can distinguish a jailbreak-assisted technique from a modified-IPA result and a stock-device customer impact.
Capstone reportYou can hand another tester the evidence and have them reproduce the result without guessing what you did.

What you will learn

You will learn the engagement, then the iOS security stack, then the assessment sequence you will reuse on a client IPA.

The engagement. Written authorization, a named target, a time box, and a statement of what you may do to the device. Without that, the same keystrokes are unauthorized access. You will also learn the claim ladder: jailbreak-required, user-space modified IPA, and stock-claimable. Every finding in this course is graded against that ladder.

The standard. You test against OWASP MAS. MASVS is the control standard (what the app should do). MASWE names the weakness. MASTG is how you test. The Mobile Top 10 2024 is the risk language you use on the report call. You will cite those on MediVault findings, not a blog category list.

Static analysis. You will take the IPA apart before it runs: Info.plist, entitlements, privacy manifest, Mach-O, strings, hardcoded endpoints, placeholder pins, third-party SDKs, and the CoreML model. The artifact you keep is the attack-surface map.

Network. Burp on the Mac, system proxy on the guest. You will map pinned API traffic versus unpinned telemetry, identify certificate pinning, bypass it two ways (SSL Kill Switch 3 and Frida), and stay honest about the mock backend.

Runtime. Typical iOS functions (jailbreak checks, pinning, login/session, biometrics, secrets), then the intervention: Frida 17, Objection, frida-trace, heap inspection, debugserver, tweaks, Gadget, and Web Inspector as the rest of the kit. Every runtime change begins with an objective and ends with before-and-after evidence.

Data at rest. Container walk as mobile and as root. UserDefaults, App Groups, SQLite, Keychain, snapshots, pasteboard, unified logs, file-protection classes, and the unencrypted-backup parse (Manifest.db) as a method this VM cannot complete. You will recover the same planted patient identifiers from more than one store.

Authentication and cryptography. Mock login, session tokens, LAContext as a UX gate versus Keychain ACL as a crypto gate, App Attest as an honest negative on this research VM, and the planted software-backed medication key.

IPC and WebView. URL schemes (uiopen), App Group writes, pasteboard exposure, and WKWebView bridges (patientDataHandler, sessionManager, mediVaultBridge) with no origin check.

RASP and patching. Detector map, non-inline bypass, ElleKit tweaks, opainject, byte patch, insert_dylib, Frida Gadget, TrollStore reinstall. You will record whether the bypass required a jailbreak.

The report. Replayable evidence, CVSS for mobile, findings written so they get fixed, a capstone assessment of MediVault with claim rungs on every title, and a day-one playbook for when the next IPA is not MediVault (FairPlay cryptid 1, TrustKit, OAuth).

How the course is organized

Eleven phases, 77 modules. Phase 00 is the workbench. Phases 01 through 10 are the assessment.

PhaseYou will learn toMASVS group
00Stand up SSH, Frida 17, and Burp on the guestLab only
01Scope the job and read AMFI, signing, and the sandboxEngagement (01.1) plus MASVS-PLATFORM
02Read the IPA as a bundle and keep an attack-surface mapMASVS-CODE, MASVS-PLATFORM, MASVS-PRIVACY
03Proxy traffic, kill pinning two ways, write network findingsMASVS-NETWORK
04Change what the running app believes: typical functions, Frida, Objection, other runtime tacticsTechnique used against every group
05Walk data at rest as mobile and as rootMASVS-STORAGE
06Test login, session, biometrics, and keysMASVS-AUTH, MASVS-CRYPTO
07Abuse URL schemes, App Groups, and WKWebView bridgesMASVS-PLATFORM
08Map RASP, bypass without touching __TEXT, triage crashesMASVS-RESILIENCE
09Patch, inject a dylib, embed Frida Gadget, reinstallMASVS-RESILIENCE, MASVS-CODE
10Package evidence, score with CVSS, deliver the capstoneCitations and the claim ladder

This course is not iOS Vulnerability Research. Kernelcache carving, IOKit user clients, and panic triage belong to the separate iOS Vulnerability Research track. Application assessment and platform vulnerability research have different scopes, evidence standards, and impact claims.

Who this is for

You may be running your first mobile assessment. You may already hook ObjC for a living. Both are in scope.

If you are new: every term is defined before it is used. Sandbox, AMFI, IPA, Frida attach, TrollStore, MASVS, and RASP are not assumed knowledge. Read the definition, then the mechanism, then the command.

If you already assess iOS apps: the mechanism sections are still required reading. The lab is iOS 26.1 on a jailbroken research VM. Frida-server does not load as a LaunchDaemon on this custom firmware. PATH on SSH is empty until you export /var/jb. Those are not beginner footnotes. They are why captures in this course will not match a blog written against iOS 14.

The standard you test against

The industry standard for mobile application security is the OWASP Mobile Application Security (MAS) project. You will use four of its deliverables. They are not four names for the same document.

OWASP MASVS (Mobile Application Security Verification Standard) is the control standard. It states what a mobile app is expected to do. MASVS v2 groups those expectations into eight control groups:

GroupWhat it covers
MASVS-STORAGESecure storage of sensitive data on the device (data at rest)
MASVS-CRYPTOCryptographic functionality used to protect sensitive data
MASVS-AUTHAuthentication and authorization mechanisms used by the app
MASVS-NETWORKSecure network communication with remote endpoints (data in transit)
MASVS-PLATFORMSecure interaction with the OS and with other installed apps
MASVS-CODESecure data processing and keeping the app up to date
MASVS-RESILIENCEResilience to reverse engineering and tampering
MASVS-PRIVACYPrivacy controls that protect the user

A control is a requirement, not a bug. MASVS-CRYPTO-1 (the app employs current cryptography and uses it according to best practices) is what the client asked the product to satisfy. Your finding is the evidence that it does not.

OWASP MASWE (Mobile Application Security Weakness Enumeration) catalogs weaknesses that can cause MASVS controls to fail and complements broader taxonomies such as CWE. Example shape: a MASVS-STORAGE-1 miss may be catalogued as unencrypted sensitive data in private storage. You will attach the applicable current MASWE identifier when you write the finding in Phase 10. You will not invent identifiers. The live catalog is mas.owasp.org/MASWE.

OWASP MASTG (Mobile Application Security Testing Guide) is how you test: procedure, technique, and tool. When a later module says "dump the App Group suite" or "confirm the pin compare at runtime," that is MASTG-shaped work even when the module cites a Frida script instead of a MASTG test ID.

OWASP MAS Checklist is the worksheet. It maps MASVS controls to tests so you can demonstrate coverage instead of sampling whatever was easy to hook. The capstone is MediVault evidence, not a ticked spreadsheet.

The course does not use the retired L1 / L2 / R labels as a substitute for scope. Cover the current MASVS controls that apply to the target, record what was not tested, and use the current OWASP MAS catalog when assigning identifiers.

Risk language: OWASP Mobile Top 10 2024

The OWASP Mobile Top 10 2024 is a risk ranking. It is the vocabulary you use on the opening call when a CISO asks what class of problem you found. It is not a complete test plan. Ten bullets cannot replace eight MASVS groups plus the MASWE catalog.

UseArtifact
What should the app do?MASVS control group and control ID
What is wrong?MASWE (and CWE when it adds precision)
How did you test it?MASTG procedure plus the command and screenshot in this course
How do you say it on the call?Mobile Top 10 2024 category
How severe is it?CVSS, taught in 10.2, with mobile context

Where those categories show up on MediVault:

IDCategoryIn this course
M1Improper Credential UsageMock session tokens, planted clinician material (Phase 06)
M2Inadequate Supply Chain SecuritySDK and CoreML inventory (02.6). Only report a supply-chain issue if it is present in the IPA.
M3Insecure Authentication/AuthorizationMock login, medivault-auth:// session injection (06, 07)
M4Insufficient Input/Output ValidationURL schemes and WKWebView bridges (Phase 07)
M5Insecure CommunicationPlaceholder SPKI pins, cleartext RASP telemetry (Phase 03)
M6Inadequate Privacy ControlsPasteboard, snapshots, unified logs, planted clinical records (05, 07)
M7Insufficient Binary ProtectionsRASP that detects and reports but does not hard-block (Phase 08)
M8Security MisconfigurationFile-protection mix, local networking exceptions (03, 05)
M9Insecure Data StorageApp Group plaintext, SQLite, unprotected JSON cache (Phase 05)
M10Insufficient CryptographySoftware-backed medication key next to an Enclave-backed patient key (Phase 06)

Do not cite the 2016 Mobile Top 10 (M1 Improper Platform Usage through M10 Extraneous Functionality) on a current report. That list is superseded.

A worked citation, so the shape is concrete before you have dumped a database. MediVault accepts any non-empty Clinician ID and password, then issues a mock-session-* token. When you write that finding (MV-04, Phase 06) it looks like this:

  • Control: MASVS-AUTH.
  • Risk language: M3 Insecure Authentication/Authorization. M1 if you are talking specifically about the token as a credential.
  • Claim: stock-claimable. You observe it from the UI on an unmodified IPA. No jailbreak is required for the proof.
  • Out of bounds: "authentication bypass of api.medi-vault.com." That host is not a live backend. The app always fires a pinned request there, then falls through to the mock. Overclaiming a dead API is a failed finding.

Phase 10 attaches the current MASWE identifier and a CVSS vector.

What is not an iOS test catalog

Other documents show up in client mail. They constrain the report audience. They are not the procedure you run on an IPA.

PTES and NIST SP 800-115 describe the shape of a professional test: authorization, scoping, discovery, attack, reporting. 01.1 operationalizes that shape. They do not tell you how to read an entitlements plist.

Apple Platform Security is how iOS actually works (AMFI, sandbox, Keychain, Secure Enclave). You will measure those facts on the guest in 01.2 and 01.3. You will not treat that document as a pass/fail checklist for MediVault.

PCI DSS applies when the target handles payment card data. MediVault does not. Do not paste PCI requirement numbers into these findings.

HIPAA (and similar clinical-privacy regimes) applies to covered entities handling electronic protected health information. MediVault is a training app. The planted rows are shaped like medical record numbers so you practice evidence handling. You are not performing a HIPAA Security Rule audit. You will not title a finding "HIPAA violation." You will title it as the control failure. Phase 10 shows how to point at the technical control if a real client's counsel later asks for HIPAA-relevant language.

ISO 27001 / SOC 2 are organization-level programs. They may be why the client hired you. They are not MASVS-STORAGE-1.

If a statement of work names both MASVS and a compliance regime, you still test MASVS. You then phrase impact in the language the audience reads.

The lab

The guest is a virtual iPhone booted with vphone-cli.

The virtual iPhone environment used in this course is powered by vphone-cli, an MIT-licensed project by Lakr233. Follow the upstream project documentation for host preparation and guest creation.

This course does not teach you how to install vphone-cli, relax SIP/AMFI on the Mac, run vm create, or complete first boot. Those steps are documented by the project author on GitHub, including host prerequisites, firmware variants (less, regular, dev, jb, exp), SSH (mobile on port 22222, password alpine for the jb variant), and VNC. Read that README and the linked docs before 00.2. If the guest is not booted, stop here and finish that guide. We will not duplicate it.

What this course does teach is how to use a booted jb guest as an assessment lab: SSH with a correct PATH, Frida 17 from the Mac, Burp on the host, TrollStore for IPA install, and MediVault as the only in-scope target.

The guest you will work against is identified below. These captures were taken on the validation lab. Yours must match on product version and architecture. DHCP may assign a different 192.168.64.x address. Re-check with arp after every relaunch.

vphone lock screen running iOS 26.1
Validation guest, lock screen. ProductVersion 26.1, device class iPhone99,11.

Identify the guest before you trust it

SSH as mobile. Dropbear listens on 22222. The login shell does not put Procursus on PATH. If you skip the export, sw_vers and uname will fail with command not found. That is expected on this firmware, not a broken install.

host → guest identity
% ssh -p 22222 mobile@192.168.64.3
% export PATH=/var/jb/usr/bin:/var/jb/bin:/var/jb/usr/sbin:/usr/bin:/bin:/usr/sbin:/sbin
% id
% uname -a
% sw_vers
uid=501(mobile) gid=501(mobile) groups=501(mobile)
Darwin iPhone 25.1.0 Darwin Kernel Version 25.1.0: Thu Oct 23 11:11:48 PDT 2025; root:xnu-12377.42.6~55/RELEASE_ARM64_VRESEARCH1 iPhone99,11 arm Darwin
ProductName:    iPhone OS
ProductVersion: 26.1
BuildVersion:   23B85

Read four fields, in this order.

uid=501(mobile). You are the unprivileged app user. Root is available with sudo (password alpine). Engagements on a client device do not give you this. When a later module uses sudo sqlite3 /var/Keychains/keychain-2.db, that evidence is jailbreak-required unless you also show a path that works without root.

RELEASE_ARM64_VRESEARCH1 and iPhone99,11. This is a research virtualization identity, not a shipping iPhone SKU. App Attest, DeviceCheck, and controls that bind to genuine hardware may fail or return environment-specific results here. Record those outcomes as environment-bounded negatives, not as "the app is broken." MASVS-AUTH still requires you to identify whether App Attest is implemented. This research guest cannot demonstrate that it works on physical hardware.

ProductVersion: 26.1 / BuildVersion: 23B85. Pin your notes to this pair. Pinning bypasses, Frida-server start method, and AMFI sysctl values are version-specific. If your guest is a different build, do not paste this course's output as yours.

Darwin 25.1.0. Kernel userland major lines up with iOS 26. You are not on an iOS 14 ramdisk image.

Confirm Frida can see the target from the Mac. Frida-server must already be running on the guest (00.6 covers start; LaunchDaemons are rejected by this CFW, so the validated method is nohup).

Mac host, Frida 17.17.0 against the guest
% frida-ps -H 192.168.64.3 | grep MediVault
12797  MediVault

A numeric PID plus the process name MediVault is attachable. If this line is missing, the app is not running or frida-server is not listening on 0.0.0.0. Do not continue Phase 04 until this command returns a row.

What you should see on SpringBoard

Unlock the guest. The second home screen on the validation image carries the three packages this course depends on.

SpringBoard showing Sileo, TrollStore Lite, and MediVault
Validation SpringBoard. Bottom row: Sileo, TrollStore Lite, MediVault.

Sileo is the graphical front end to apt on Procursus. Jailbreak packages (Frida, SSL Kill Switch 3, PreferenceLoader, ldid) install through it or through apt-get over SSH. Do not apt-install ellekit on this custom firmware. The postinst replaces TweakLoader.dylib and tweak injection dies after reboot. That constraint is a lab rule, not a suggestion.

TrollStore Lite installs an IPA with a persistent signature. You will use it to put MediVault on the guest and to reinstall a patched binary after Phase 09. It is not the App Store. It is not Xcode devicectl. It is the install path this jailbreak gives you.

MediVault is the in-scope application, bundle id com.macseclabs.medivault, version 2.4.1. You will not load other vendors' IPAs into this course.

Why the simulator is not the evidence environment

The iOS Simulator shares the Mac kernel. AMFI policy, Keychain, App Attest, and the network stack are not the ones a fielded iPhone enforces.

For this target, the simulator does not reproduce the code-signing, Keychain, App Attest, Secure Enclave, and runtime-protection conditions measured by the course. You may compile MediVault for the simulator to inspect source and UI behavior. Do not use simulator output as evidence for a physical-device security claim.

A physical jailbroken iPhone is a useful technique environment, but reproducibility depends on hardware and jailbreak availability. The virtual guest gives every student iOS 26.1, the same Procursus userland, and the same MediVault build. That consistency makes the captures comparable while the claim ladder prevents the lab from being mistaken for a stock-device proof.

The claim ladder (required on every finding)

A jailbroken research VM is a technique lab. A client engagement is usually a stock device plus an IPA you are allowed to install under the contract. Those two environments do not produce interchangeable evidence. MASVS does not care that you had root. The client's risk committee does.

Classify every finding before you write the title:

  1. Jailbreak-required. The proof used root, a tweak, opainject, frida-server, or a path under /var/jb. State that in the finding. Example: reading /var/Keychains/keychain-2.db with sqlite3.
  2. User-space, modified IPA. The proof still works after resign or Gadget injection without root on the live device. State the install method.
  3. Stock-claimable. The proof is valid on an unmodified IPA on a non-jailbroken iPhone the client would actually ship. This is the only rung that may be written as a default customer impact.

The capstone is graded against this ladder. A jailbreak-only keychain dump reported as a stock-device credential theft is a failed finding, even if the dump is technically correct and even if you cited MASVS-STORAGE.

The target after authentication

MediVault accepts any non-empty Clinician ID and password. The UI label is "Clinician ID", not username. Sign In stays disabled while either field is empty. A working pair on the validation build is npi-1001 / medivault.

MediVault login screen with Clinician ID field
Login surface. MASVS-AUTH. The mock acceptance behind this screen is finding MV-04.

The app always issues a pinned HTTPS request to https://api.medi-vault.com/v2/auth/login first. That host is not a live backend. The request is for Burp (Phase 03). Login then falls through to a mock session. Treat that as missing authentication, then write it with the citations in the worked example above.

After sign-in the validation guest shows this list.

MediVault Patients list after mock login
Patients tab after mock login. Five seeded records. Clinical identifiers are on screen by design.

The rows are planted. James Wilson MRN-2026-0042, Maria Garcia MRN-2026-0187, Robert Kim MRN-2026-0312, Emily Thompson MRN-2026-0551, David Nakamura MRN-2026-0723. You will recover the same identifiers from SQLite, from an App Group suite, from the pasteboard, from a WKWebView bridge, and from unified logs. Those recoveries are MASVS-STORAGE, MASVS-PLATFORM, and MASVS-PRIVACY work. If a later module's capture shows a different MRN, the seed changed and the module must be recaptured.

Tabs: Patients, Diagnosis, Telehealth, Settings. Telehealth hosts a local HTML page that talks to patientDataHandler, sessionManager, and mediVaultBridge. That is Phase 07. Do not skip ahead without the static map from Phase 02.

What Phase 00 still owes you

ModuleWhat you will be able to do
00.2List host requirements (Apple Silicon, SIP/AMFI as documented by vphone-cli, Burp, Frida 17). No install walkthrough.
00.3Confirm a booted jb guest against sw_vers and device identity.
00.4SSH as mobile and put /var/jb on PATH.
00.5Name the on-guest packages and the ellekit/TweakLoader constraint.
00.6Start frida-server with nohup and confirm frida-ps -H.
00.7Write the guest HTTP proxy, bind Burp, install the CA, intercept a request.

If the guest is already booted and MediVault is on SpringBoard, you still read 00.2 through 00.7. They document failure modes you will hit on day two (empty PATH, LaunchDaemon rejection, proxy applied only at boot).

Out of scope

  • Installing vphone-cli, disabling SIP, or creating the VM. Use the vphone-cli project documentation.
  • Jailbreaking a physical iPhone.
  • Kernel research, IPSW extraction, or panic logs.
  • Full rules of engagement, SoW language, and evidence retention. That is 01.1.
  • Walking every MASWE identifier. Phase 10 attaches IDs to written findings.
  • Reporting MediVault mock-login as a production authentication bypass against a live API. There is no live API. The finding is client-side acceptance of unauthenticated sessions.
  • Treating PCI, HIPAA, ISO 27001, or SOC 2 as iOS test procedures.

Next

00.2 verifies what must already be true on the Mac before you type ssh: supported hardware, the upstream host prerequisites, the required tooling, and a booted guest. From there, the assessment starts at the host shell and every later claim must trace back to captured evidence.

Continue the iOS Application Pentesting track

Full access includes all assessment phases, progress tracking, the MediVault target, and the gated script library.

Get full access