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:
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 planindex.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¶
- 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.
- 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. - 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.