Listen to an iPhone's HTTPS traffic from the Mac to find where an app fetches data/images. Sets up mitmproxy, walks the iPhone proxy+cert setup, then locates and extracts API endpoints. Trigger when the user wants to "sniff iphone traffic", "intercept app traffic", "see where an image/app loads from", "MITM my phone", or inspect an app's API calls.
Unzip into your Claude skills directory (e.g. ~/.claude/skills/) or your project's .claude/skills/ to use it.
Goal: see the decrypted HTTP(S) calls an iPhone app makes (from the Mac), find the
endpoint/image a screen loads, and optionally replay it to download assets.
Legitimate use only: the user's own device + own network/account. Stop if it's not.
command -v mitmweb mitmdump mitmproxy # need mitmproxy (brew install mitmproxy)
ls ~/.mitmproxy/mitmproxy-ca-cert.pem # CA cert (auto-created on first run)
ipconfig getifaddr en0 || ipconfig getifaddr en1 # Mac Wi-Fi IP — phone points heremitmweb's auto token is awkward over a background pipe — set a known password instead.
mitmweb --no-web-open-browser --web-host 127.0.0.1 --web-port 8081 \
--listen-port 8080 --set web_password=iris --set stream_large_bodies=1mlsof -nP -iTCP:8080 -sTCP:LISTEN-w /tmp/flows.mitm, then read later with mitmdump -nr /tmp/flows.mitm. (mitmweb's stdout is block-buffered and lags — the
web UI / -w file are the source of truth, not the background task output.)
8080..pem on the Mac is useless): Safari →http://mitm.it → tap the Apple icon → Allow → install the profile in
Settings → General → VPN & Device Management.
Settings → toggle mitmproxy ON**. This is the step that's always skipped.
User opens https://example.com in Safari:
different tool's cert, e.g. Proxyman — check the profile name is mitmproxy). Redo 2.3.
~t image (image responses), ~m GET, or a hostname.Read the proxy log / flows. The signatures:
| Symptom | Meaning | Fix |
|---|---|---|
| Client TLS handshake failed … client disconnected | App rejects our cert | Trust not enabled (§2.3) or the app pins certs (§6) |
| App shows "connection error", log frozen | Traffic not reaching Mac, or all conns fail | Re-check proxy IP (it can change), firewall, :8080 listening |
| Only mitm.it/analytics flows, app silent | Cert untrusted → only HTTP got through | §2.3 |
| Safari "not private" | OS-level trust missing | §2.3 |
If handshakes keep failing after trust is confirmed, the app pins its cert — it
hardcodes the expected cert and rejects mitmproxy's regardless of OS trust. A plain proxy
can't beat this. Options:
palera1n,unpatchable bootrom) on any iOS incl. 16/17 → install SSL Kill Switch 3 / A-Bypass
in Sileo to disable pinning system-wide. *(A11 + iOS15/16: remove the passcode first or it
boot-loops; semi-tethered, re-run palera1n after each reboot.)*
frida-multiple-unpinning) or apk-mitm is often easier.server connect …) — useful formapping which CDNs/APIs an app talks to without decrypting.
Once you see the API:
Origin/X-Origin or a Bearer token. Copy them from a captured Request → Headers.
/tmp/<app>_token.txt) to keep commands clean; tokens expire (decode the JWT exp), so grab a fresh one if calls start returning 401.
T=$(cat /tmp/app_token.txt)
curl -s -H "origin: <captured-origin>" -H "authorization: Bearer $T" \
-H "accept: application/json" "https://api.example.com/v1/<resource>" | python3 -m json.tool
curl -sL '<signed CDN/S3 url>' -o ~/Desktop/asset.jpg # presigned URLs need no auth, expire fast
…/blobs/redirect/<signed-id>/<name>) 302 to a presigned S3/GCS link; the bucket name often reveals quality tiers (…-thumbnails,
…-originals, …-preview). Check resolution: sips -g pixelWidth -g pixelHeight file.jpg.
X-Padding header full of junk JSON (often the famous Foursquare "Central Park" sample, quotes swapped for *): deliberate size-obfuscation filler to defeat traffic analysis.
Not real data — ignore.
*.ess.apple.com hosts: third-partyanalytics, usually pinned and irrelevant to the target.
pkill -f mitmwebConfigure Proxy → Off) — otherwise no internet once the Mac proxy stops.
rm /tmp/*_token.txt) and temp flow files.