DOCUMENTATION / PART 5 — TECHNIQUE REFERENCE5.5

5.5 The SIM and the handset

The SIM is the one part of the system that is supposed to be a safe. Everything in this family is either reading it, writing to it through the over-the-air channel, or detecting that somebody else has moved it.

5.5.1 Read a USIM

Need: a reader (or nothing, for the codec layer). Nearly every technique that needs a credential starts with the same three commands: select a file, read it, decode it.

modules/16_sim.sh --file-id 6f07                       # what file this id is
modules/16_sim.sh --select-fid 6f07                    # the SELECT APDU (A0 A4 00 00 02 6F07)
modules/16_sim.sh --read-binary 0 10                   # READ BINARY
modules/16_sim.sh --read-record 1 04                   # READ RECORD, absolute mode
modules/16_sim.sh --get-response 10                    # GET RESPONSE
modules/16_sim.sh --decode-iccid 89012604201000000010  # EF_ICCID -> ICCID, Luhn checked
modules/16_sim.sh --parse-apdu <hex>                   # command or response, in either direction

The APDU verbs are pure codecs: they produce the bytes and do not touch a card, which is why they work with no reader attached. --decode-iccid is the useful demonstration of why a codec beats a hex editor — ICCID is nibble-swapped BCD with a Luhn check digit, and reading it wrong is how a lab ends up with two labels for one card.

What you read: the APDU case (1, 2, 3 or 4), the file identity and size, and for a decoded record the field layout. --status-tsv reports whether a reader and pcscd are present, so a failed read is attributable.

When it refuses: a file id it has no name for is reported as unknown rather than mapped to a guess; an APDU whose length fields contradict its data is refused by length.

Read next: §5.5.2 for writing to the card over the air, and §5.5.4 for the defensive side of the same files.

5.5.2 Over-the-air SMS and the SIM toolkit

Need: nothing for the codecs; a network path and keys for a live delivery. OTA SMS is how an operator provisions a card without touching it — and therefore how anyone who can forge an OTA SMS provisions a card without touching it.

modules/41_ota_sms.sh --spi-build 11 2 1                  # SPI: cipher, counter, PoR settings
modules/41_ota_sms.sh --packet 02 0000 1 <spi> 1 1 <data>  # one command packet
modules/41_ota_sms.sh --packet-sms 0000 1 <spi> 1 1 <apdu>  # the same over SMS-PP
modules/41_ota_sms.sh --parse-packet-sms <hex>           # decrypt it and check its CC
modules/41_ota_sms.sh --parse-resp-sms <hex>             # the card's Response Packet

modules/52_stk.sh --build <type> <qualifier>             # a proactive command
modules/52_stk.sh --parse <hex>                          # decode one
modules/52_stk.sh --audit <log>                          # flag silent off-device commands
modules/52_stk.sh --sat-cmds                             # the S@T command surface

The pairing is deliberate: 41 builds and reads the envelope (SPI, KIC, KID, counter, ciphering), 52 builds and reads what is inside it (the proactive command the card is told to run). --audit is the defensive verb — it flags proactive commands that would send data off the device without the user seeing anything, which is the signature of a card being used as an exfiltration channel.

What you read: for a packet, the SPI and whether its counter is plausible; for a proactive command, the type, the destination and whether it is silent. --spi parses an SPI on its own and reports which parts of it are weak.

When it refuses: a packet whose CC (check) does not match; a counter that repeats when the cipher is not a stream that tolerates it.

Read next: §5.5.4 for what a subscriber can do about a card that has already been written to.

5.5.3 USSD and MMI strings

Need: nothing. USSD is the only signalling channel that reaches a handset without a data session, and MMI strings are the only interface a user has to supplementary services.

modules/38_ussd.sh --pack 'hello'                # GSM 7-bit packing, with extension chars
modules/38_ussd.sh --unpack e8329bfd06           # back again
modules/38_ussd.sh --build 15 'hello'            # a USSD facility message
modules/38_ussd.sh --mmi '*#100#'                # parse an MMI string
modules/38_ussd.sh --ss-codes                     # supplementary-service reference
modules/38_ussd.sh --detect <payload>             # USSD/STK injection findings
modules/38_ussd.sh --plan                         # the lab handoff plan

Two things make this worth its own page. First, 7-bit packing is where most home-grown USSD tools break on characters outside the default alphabet; the extension table is implemented and asserted. Second, --detect reads a payload looking for injection: USSD strings that are passed to a modem without escaping are a command channel into the device.

What you read: the packed septets and the unpacked text; for --mmi, the service code, the supplementary information and the SIA part; for --detect, the specific construction it objects to.

When it refuses: a packed string whose declared septet count does not match its length.

Read next: §5.5.2, since a USSD or STK payload is often the delivery vehicle.

5.5.4 Detect a port-out or a clone

Need: history. This is the defensive counterpart of everything else in the manual: what a subscriber, or the operator watching for them, can actually check.

modules/31_sim_defense.sh --signals              # the six detection signals, with meaning
modules/31_sim_defense.sh --score <history-tsv>  # port-in-progress likelihood
modules/31_sim_defense.sh --pin-state            # PIN/PUK retry counters and the ADM key
modules/31_sim_defense.sh --ef-ad <hex>          # EF_AD in either layout
modules/31_sim_defense.sh --defence-checklist    # what a subscriber can enforce
modules/31_sim_defense.sh --esim-profile-parse <hex>

The six signals are the page: an IMSI pairing with a new IMEI, an OTA-SMS burst, an authentication-failure streak, dual-network registration, and two more of the same kind. Each is individually weak and collectively diagnostic, which is why --score reports a likelihood with the signals that produced it rather than a verdict. --defence-checklist is the only page in the manual that is a list of things to turn on rather than things to try.

What you read: per signal, whether it fired and what it means in one sentence; for --score, the likelihood and its inputs.

When it refuses: a history file that is not the expected TSV; an EF_AD hex whose layout is ambiguous is reported in both layouts rather than one.

Read next: §5.5.1 for the files these signals concern, and §5.9.3 for the interception side of a port.