Skip to content

Phase D.6.5 control — lockdown back-connect hypothesis FALSIFIED

Status: verified — completed 2026-04-24

Control experiment: re-ran the iter-09 wide-pcap methodology on the SPIKE backend but with devicectl device info details as the trigger (the one that iter-10 showed caused lockdown traffic against the real iPhone). Expected a SYN to [::1]:50367 followed by ECONNREFUSED. Actual: exactly one SYN — client→our backend on :34719 — identical shape to iter-09. Zero SYNs to any advertised service port. Zero RSTs. CDS does NOT back-connect to the advertised lockdown port in SPIKE mode, regardless of trigger. Full writeup: findings.md.

D.6.6 plan revised: research-a (Properties dict diff) + research-b (field-bisection patching) now precede the original lockdown-handler implementation step.

What D.6.5-control falsified

D.6.5 implementation sketch assumed: "CDS reads Services dict from our Handshake, opens TCP to :50367, fails with ECONNREFUSED because SPIKE has no listener → that's the Mercury 1000 error cause; implementing a lockdown handler fixes it."

Actual behaviour: CDS bails upstream of consulting Services dict. Something in CDS's post-handshake evaluation reads our SPIKE Handshake as "unpaired / untrusted" and aborts before the lockdown back-connect phase. devicectl surfaces pairingState: unpaired and tunnelState: unavailable + Mercury 1000 — same symptom as iter-10 against a real iPhone under devicectl (which also reported unpaired).

Revised causal model

Previous:

SPIKE Handshake OK
  → CDS reads Services
  → CDS SYNs :50367
  → ECONNREFUSED
  → Mercury 1000

Revised:

SPIKE Handshake OK at wire level
  → CDS evaluates some pair/trust signal
  → signal reads "unpaired / untrusted" in SPIKE
  → CDS bails before Services dict consultation
  → Mercury 1000

Important nuance from iter-10 re-reading

iter-10's 50367 flow was opened by pymobiledevice3 lockdown info, not by devicectl. These two clients differ:

client trust-gating before lockdown?
pymobiledevice3 no — connects directly to advertised ports
devicectl (via CDS) yes — requires trust check to pass first

In SPIKE mode we only interact with CDS/devicectl. CDS's trust gate is the missing variable.

Files

  • findings.md — full decode, SYN table, causal model revision, candidate trust-signal locations (H-Adv / H-HS / H-Tx), revised D.6.6 plan
  • index.md — this summary

Pcap (42 packets, ~2 KB) and verbose log stay at /tmp/iosmux-d12-* — trivial, re-generable from the scripts.

Revised next steps

  1. D.6.6-research-a: byte-diff our SPIKE Handshake Properties dict against real iPhone Handshake Properties (both available in iter-10 pcap + our fixture). Identify every differing field.
  2. D.6.6-research-b: env-gated per-session patching of each candidate field (same mechanism as D.6.1 UUID patching). Re-run wide pcap. Field that triggers SYN to :50367 = the trust gate.
  3. D.6.6-impl: implement the lockdown handler at :50367, unblocked by (a)+(b) findings.

Estimated total: ~2-4 days vs the original ~1-day D.6.6 plan. The one-day implementation effort is still correct, just preceded by a research prerequisite.

Operational note

macOS has no GNU timeout(1). Scripts needing a time-bounded command on havoc should use & + poll + kill pattern from the start. Documented here so future iter scripts avoid this snag.