DOCUMENTATION / PART 5 — TECHNIQUE REFERENCE5.3

5.3 Standing up a cell of your own

A catcher asks a question. A rogue cell changes the answer. Everything in this family is a way of being a network the handset will believe — and every one of them has the same cost: a real radio, a licence you do not have unless you are in a shielded room or hold one, and a plan file you should read before you key anything.

Two modules in this family are unusual in the toolkit because they are honest about being unfinished: 57_evil_twin and 60_overshadow both have a preflight that reports every remaining precondition rather than starting and failing later.

5.3.1 The evil twin

Need: a survey (§5.1.6) to clone, and a radio to radiate.

modules/57_evil_twin.sh --prepare-lte loot/cell_recon/cells.tsv 3 --pci 42 --out loot/evil-twin
modules/57_evil_twin.sh --preflight-lte loot/evil-twin      # what the twin still needs
modules/57_evil_twin.sh --run-lte loot/evil-twin 120 --radiate --with-capture --iface lo
modules/57_evil_twin.sh --evidence-collect loot/evil-twin --rat lte --run twin-1
modules/57_evil_twin.sh --evidence-tsv --run twin-1

--prepare-lte reads one row of a survey and writes a configuration directory in which every field is traceable to that row: the PLMN, the TAC, the cell identity, the EARFCN. --preflight-lte is the interesting verb — it lists what is missing (a core, a radio, a key) and refuses to start until each is satisfied, which is the difference between a lab exercise and a failed transmission.

--evidence-collect has the honesty property the whole module is built around: each evidence row is marked observed or advertised. An advertised row is what the twin claims (the PLMN it broadcasts, the EARFCN it sits on); an observed row is what a real receiver or a real handset actually did (attached, sent an IMSI, sent an IMEI). A run that produced six advertised rows and no observed rows is a run where the twin radiated and nobody believed it.

What you read: the evidence table, with the confidence column deciding what you may claim. The twin-feed window (§4.13.6) draws both kinds, with the advertised rows visibly worn.

When it refuses: every verb needs a prepared directory and says which; a missing radio is listed by --preflight-* rather than discovered at transmit time.

Read next: §5.3.2 for what to do when the handset refuses to attach, and §5.2.6 for how the same twins are detected.

5.3.2 Overshadowing and AdapOver

Need: a radio, and a plan. Overshadowing is the technique of making a legitimate cell unreadable at the moment a message must be read, so that the handset takes a signal you sent instead. It does not break ciphering; it removes the message that would have told the handset to distrust you.

modules/60_overshadow.sh --info                 # what this module does and refuses to do
modules/60_overshadow.sh --needs                # bill of materials (b210, b205mini, x310, pluto)
modules/60_overshadow.sh --timing-budget        # receive instant to transmit instant vs 2 ms and CP
modules/60_overshadow.sh --power-budget         # required power and range for ul / dl modes
modules/60_overshadow.sh --subframe-map <tsv>   # which subframe and RBs carry which message
modules/60_overshadow.sh --plan <target>        # sample-indexed schedule
modules/60_overshadow.sh --collateral           # what breaks around the target
modules/60_overshadow.sh --detect <tsv>         # unscheduled TB, SIB change without paging, drift

--timing-budget and --power-budget are the two pages to read before believing anybody's claim about this technique, including this module's. Overshadowing is a deadline problem (the replacement must arrive inside a window measured in microseconds) and a power problem (the replacement must be louder than the cell it replaces at the handset, not at your antenna). Both verbs print the arithmetic and the margin, and neither claims a plan will work — --plan produces a schedule, and the module says in its own --info that it plans and does not key.

--collateral is the honest part: a downlink overshadowing degrades the whole cell, an uplink one degrades one grant. --detect is the defensive use of the same knowledge: an unscheduled transport block, a SIB change without a paging message, or a schedule that drifts are all evidence that somebody is doing this.

What you read: the budget pages for feasibility, the plan for a schedule, and --detect for evidence.

When it refuses: --needs prints what hardware would work; every radiating verb refuses with no radio.

Read next: §5.1.3, because paging timing is the mechanism this technique disturbs, and §5.7.3 for its tracking variant.

5.3.3 Force a downgrade with a reject

Need: nothing to build, a radio to radiate. The cheapest downgrade is a message the handset is required to believe: a reject with a cause code that sends it somewhere the attacker controls.

modules/15_downgrade.sh --reject-cause 15 EMM           # what cause 15 means, from the spec table
modules/15_downgrade.sh --build-reject EMM 15 attach    # the NAS message to send
modules/15_downgrade.sh --tx-reject EMM 15 attach       # build it and put it on the air
modules/15_downgrade.sh --build-security-mode EEA0      # advertise no ciphering at all
modules/15_downgrade.sh --null-cipher-table             # A5-0/UEA0/EEA0/NEA0 across generations
modules/15_downgrade.sh --detect <pcap|records.tsv>     # find steering rejects in existing traffic
modules/15_downgrade.sh --path <name>                   # describe a downgrade mechanism

The cause table is worth knowing by heart if you work on the defensive side: cause 15 ("No suitable cells in tracking area") steers a handset to another RAT, cause 22 ("Congestion") makes it retry later, and the security-mode variants propose a null algorithm. --build-reject produces the octets and --tx-reject sends them; between the two there is no difference except the radio, which is why the module separates them — you can prepare and inspect a message on a machine with no hardware.

--detect is the reverse: it reads a capture or a procedure record and reports steering rejects, RAT changes without cause, and security modes weaker than both ends advertised.

What you read: the message and what a handset must do on receiving it; --detect for the same pattern in traffic that already exists.

When it refuses: an unknown RAT string, a cause code outside the table, a transmit with no radio.

Read next: §5.1.4 for why a null cipher is the point of the exercise, and §5.2.1 for the catcher that follows it.

5.3.4 A femtocell's own management plane

Need: nothing to build a profile; a network path for the management verbs. Small cells are the highest-value rogue target in a real deployment, because they are an operator-managed box on a consumer-grade network.

modules/37_femtocell.sh --csg-encode 12345678           # 27-bit CSG id
modules/37_femtocell.sh --cell-profile 310260 2 2500 1 # PLMN, band, EARFCN, PCI
modules/37_femtocell.sh --sib9 home-node-1             # the SIB that publishes the HNB name
modules/37_femtocell.sh --discover 10.0.0.5            # what answers on the management plane
modules/37_femtocell.sh --apply 10.0.0.5               # write the profile to it

--cell-profile emits the whole commissioning profile — PLMN, band, EARFCN, PCI, optional CSG identity and HNB name — which is the document a small cell takes as its identity. --discover then asks what management surface answers, and --apply writes the profile to a discovered surface. The two network verbs are separated from the profile verbs for a reason: building a profile is offline and safe, applying one is a change to somebody's infrastructure.

What you read: the profile as structured data, and for a live box what it claims about itself. The SIB9 name is often the give-away in a survey: it is whatever the installer typed.

When it refuses: a PLMN that is not 5 or 6 digits (a normalised 310-260 is refused; the verb wants 310260), a CSG id outside 27 bits, an unreachable management host.

Read next: §5.1.1 for the broadcast a small cell sends, and §4.13.5 for the live subscriber window the same module feeds.

5.3.5 A rogue cell at the message layer

Need: nothing. Two modules build the messages a rogue cell sends without building the cell: this is the part of the work that can be done entirely on a laptop, and the part that is worth doing before touching a radio.

modules/54_baseband_exploit.sh --forge-reg-accept           # 5G Registration Accept, plaintext
modules/54_baseband_exploit.sh --forge-reg-reject 31        # reject with a redirect cause
modules/54_baseband_exploit.sh --forge-identity 1           # identity request by type
modules/54_baseband_exploit.sh --cp-check <hex>             # control-plane property check
modules/55_nr_inject.sh --mac-pdu 1 4142434445              # a MAC-NR PDU with a chosen LCID
modules/55_nr_inject.sh --dci-parse <hex> 1_1 106           # decode a DCI against a bandwidth

The reason to separate these from §5.3.1 is that the message is the part that carries the finding. A Registration Accept in the clear is a protocol-level claim about what a core will accept; a MAC PDU with an LCID the scheduler never grants is a claim about what the receiver does with it. Neither needs a transmitter to be worth writing down, and both are refereed by their modules' selftests.

What you read: the octets plus the field-by-field construction (--l2-build <name> shows how one malformed case is assembled, --l2-case <layer> selects a layer). --cp-check reports which control-plane properties a given NAS message violates.

When it refuses: --l2-case with an unknown layer name lists the layers it knows; --dci-parse with a format it cannot size refuses rather than guessing the bandwidth.

Read next: §5.10.2 and §5.10.3, which are the same message-level work organised as a corpus.