DOCUMENTATION / PART 5 — TECHNIQUE REFERENCE5.6

5.6 Attaching, calling, and the services around them

These are the procedures a phone runs in its first two minutes on a network, and the services an operator runs on top of them. All of it is offline work: parse a capture, build a message, read what a network claims about itself.

5.6.1 Attach and the GUTI

Need: a capture, or nothing for the codec. A GUTI is the temporary identity a network hands out so the permanent one need not cross the air — which is exactly why binding a GUTI to an IMSI is the goal of half the passive work in §5.1.5.

modules/09_lte_attach.sh --decode-nas <hex>              # an EMM message and its IEs
modules/09_lte_attach.sh --setup-complete <nas_hex>      # what an ATTACH COMPLETE contained
modules/09_lte_attach.sh --guti-decode 080BF600F110123456DEADBEEF
# identity_type GUTI / plmn 001-01 / mme_group 4660 / mme_code 86 / m_tmsi 3735928559
modules/09_lte_attach.sh --guti-map <guti_hex> 001010000000001   # bind it, with evidence
modules/09_lte_attach.sh --guti-tsv                      # the bindings, attached count included
modules/09_lte_attach.sh --realloc-command <hex>         # a GUTI REALLOCATION COMMAND
modules/09_lte_attach.sh --nas-responder <file>          # hold attach state across a dialogue

--guti-map is the store write: one row per GUTI, with an attach count that increments rather than appending a duplicate, so a GUTI seen five times is one binding seen five times. --realloc-command matters because the network is allowed to change the GUTI mid-session, and a mapping that ignores reallocation silently pairs the wrong subscriber with the wrong temporary identity.

What you read: the PLMN, the MME group and code (which locate the subscriber at network granularity before any timing analysis), the M-TMSI, and the binding's evidence.

When it refuses: a hex string that is not an EPS mobile identity carrying a GUTI is refused with the identity type it actually found — the commonest error is passing the bare M-TMSI, which has no type octet.

Read next: §5.1.5 to turn a binding into a persistent identifier, and §5.7.1 for what the same attach tells you about location.

5.6.2 VoLTE, VoWiFi and the SIP edge

Need: a capture for the parsing verbs; a target for the sending verbs. Voice over LTE carries SIP inside the user plane, and the SIP is protected by the same cipher as everything else — except when it is not, and except when the operator reuses a keystream.

modules/30_volte_ims.sh --sip-parse <hex>                # a SIP request or response
modules/30_volte_ims.sh --sip-build register             # build one
modules/30_volte_ims.sh --revolte-demo <pt1> <pt2>       # same-keystream XOR demonstration
modules/30_volte_ims.sh --keystream-recover <ct> <known> # recover the keystream, decrypt
modules/30_volte_ims.sh --imp4gt-model                   # the IMP4GT sequence and preconditions
modules/30_volte_ims.sh --sip-flood register 100 512 512 # flood / amplification model

modules/36_vowifi.sh --epdg 310 260                       # epdg.epc.mnc260.mcc310.pub.3gppnetwork.org
modules/36_vowifi.sh --eap-privacy                        # what a NAI reveals before auth
modules/36_vowifi.sh --dh <n>                             # is this key exchange acceptable
modules/36_vowifi.sh --transform <n>                      # IKEv2 transform names

--revolte-demo and --keystream-recover are the honest version of the ReVoLTE finding: two calls that reuse a keystream XOR to a known value, and the module demonstrates it on chosen inputs so you can see the mechanism rather than take the paper's word for it. --imp4gt-model does the same for the identity- pointer attack and, like §5.3.2, states its preconditions up front.

VoWiFi is the same voice service over a different transport, and --epdg shows the one thing worth knowing before reading anything else: the ePDG name is derivable from the PLMN alone, which is why the tunnel endpoint is not a secret.

What you read: for SIP, the method, headers and SDP (the SDP is where the media endpoints are); for the ePDG, the FQDN and, via --validate-cert, whether the certificate that answers it is the one that name should present.

When it refuses: --dh on a group RFC 8247 forbids reports the verdict rather than the number; --validate-cert with no trust anchor says so instead of returning "valid".

Read next: §5.4.4 for the plaintext lever underneath, and §5.9.4 for the integrity gap both techniques depend on.

5.6.3 Shared RAN and PLMN leaks

Need: nothing for the codec; a capture for the leak check. A network built by one operator and shared with another still broadcasts a PLMN list, and the interesting question is whether the list is the whole story.

modules/43_ran_share.sh --plmn-encode 310 260       # 130062
modules/43_ran_share.sh --plmn-decode 130062
modules/43_ran_share.sh --eplmn '310-260,310-410'   # equivalent-PLMN list, cap 15
modules/43_ran_share.sh --mode mocn                  # sharing-mode classification
modules/43_ran_share.sh --leak-check <tsv>           # PLMN outside the broadcast set
modules/43_ran_share.sh --plan                       # two-core lab handoff plan

--leak-check is the whole point: it compares the PLMNs seen in signalling against the PLMNs the cell broadcasts, and any PLMN in the first set that is not in the second is a leak — either a misconfiguration or an interface nobody documented. --mode classifies MOCN, MORAN and GWCN, which matters because the three share different things and only one of them shares the cell identity.

What you read: the encoded PLMN, the effective list and its length limit, and the leak findings with the message they came from.

When it refuses: a fifthteen-plus-one PLMN list, i.e. more than the 15 the specification allows; a PLMN that is not 5 or 6 digits.

Read next: §5.1.1 for where the broadcast set comes from.

5.6.4 A carrier's API surface

Need: the API's own specification or a capture; nothing for the analysis verbs. Every carrier now ships a self-service API, and the security review of one is a checklist rather than an exploit.

modules/44_carrier_api.sh --openapi spec.json          # paths, servers, schemes
modules/44_carrier_api.sh --authz-matrix spec.json     # four-case test plan per operation
modules/44_carrier_api.sh --jwt-audit <token>          # alg=none, expiry, audience
modules/44_carrier_api.sh --token-bucket 10 20 100 60  # is the rate limit real
modules/44_carrier_api.sh --diff a.json b.json         # response differential between captures
modules/44_carrier_api.sh --stuffing conf.json         # credential-stuffing resistance controls
modules/44_carrier_api.sh --report                     # assessment skeleton

--authz-matrix is the valuable one: for each operation it lays out the four cases that must all be tested — owner, other user, no token, expired token — and the matrix is the finding when any cell behaves like the owner. --jwt-audit checks the three failures that account for most real breaks: unsigned tokens accepted, expiry not enforced, audience not checked.

What you read: the surface (paths, servers, security schemes) and per-operation the authorisation cases with what a pass looks like.

When it refuses: a document that is not OpenAPI 3; a token that is not a JWT.

Read next: §5.9.3, since an API is one of the lawful-intercept surfaces the same operator exposes.