CellGuard: LTE/5G-NR lock + IMSI-catcher detection KSU module
- cgcap.ko: cpif CP-frame capture via kprobe/kallsyms, stock-GKI build - ratlock.sh: hold modem to LTE+NR(5G), block 2G/3G downgrade - cgdetect.sh: always-on behavioral cell-site-simulator detection - cgctl.sh + WebUI: block/detect toggles, status + alerts - build-stock-gki.sh: reproducible stock-GKI module build pipeline
This commit is contained in:
193
common/docs/anti-forensics-hardening.md
Normal file
193
common/docs/anti-forensics-hardening.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# Rango Anti-Forensics Hardening — Case Write-Up
|
||||
|
||||
**Scope:** Owner-authorized security hardening and research on a personally-owned
|
||||
device. Goal: raise the cost of physical forensic extraction (Cellebrite UFED,
|
||||
GrayKey, XRY, Oxygen) and make the shell / low-level flash interfaces
|
||||
inaccessible without owner authorization.
|
||||
|
||||
> This document is a defensive engineering plan for the device owner's own
|
||||
> hardware. The research track (§8) is authorized vulnerability research on
|
||||
> that same device; its purpose is to understand and mitigate the attack
|
||||
> surface, not to produce a distributable exploit.
|
||||
|
||||
---
|
||||
|
||||
## 1. Objective
|
||||
- Resist forensic extraction by a physical-access adversary.
|
||||
- Deny an attacker useful access to adb, fastboot, fastbootd, recovery, and the
|
||||
USB data surface — gated behind owner authentication.
|
||||
- Keep the device usable (and rooted, for the CellGuard modem work) without
|
||||
giving that up as the price of hardening.
|
||||
|
||||
## 2. Device baseline (as-found)
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Device | Pixel 10 Pro Fold (`rango`), Tensor G5, Shannon 5400 modem |
|
||||
| Kernel | stock GKI `6.6.102-android15-8-g6eb5b2a8c46b-ab14739656-4k` |
|
||||
| Kernel hardening | RANDSTRUCT_NONE, CFI_CLANG (strict), MODVERSIONS, LTO_NONE, MODULE_SIG_PROTECT, MODULE_SIG_FORCE **off** |
|
||||
| Root | KernelSU **LKM** |
|
||||
| Bootloader | **unlocked** (props spoofed to locked/green to pass Play Integrity) |
|
||||
| adb | USB + wireless both enabled; `ro.adb.secure=1`; 1 authorized host key |
|
||||
|
||||
## 3. Threat model
|
||||
- **Adversary:** forensic extraction appliance with physical possession.
|
||||
- **Primary vectors:**
|
||||
1. **USB attack surface** — adb, fastboot (ABL), fastbootd (userspace), the
|
||||
USB gadget/MTP stack. The port is the appliance's front door.
|
||||
2. **Lockscreen brute force** — throttled by Titan M2, but exploits + time
|
||||
erode a short PIN.
|
||||
3. **AFU key residency** — After First Unlock, disk-encryption keys are in RAM
|
||||
and the secure element has seen the credential → extraction is far easier
|
||||
than the Before-First-Unlock (BFU) state.
|
||||
4. **Unlocked bootloader** — while unlocked, `fastboot boot <img>` runs an
|
||||
attacker image *instead of* the owner OS, bypassing any in-OS defense.
|
||||
|
||||
## 4. Boot chain & trust anchors — what the owner can and cannot control
|
||||
```
|
||||
bootrom (fused OEM key) → bl1 → bl2 → bl31 (EL3) → pbl → ABL (fastboot)
|
||||
→ boot / init_boot (kernel + ramdisk) → Android userspace
|
||||
```
|
||||
| Stage | Owner-controllable? | How |
|
||||
|---|---|---|
|
||||
| bootrom, bl1/bl2/bl31, pbl, **ABL/fastboot** | ❌ | bootrom-anchored to the OEM key; cannot be re-signed |
|
||||
| **boot / init_boot / vendor_boot / recovery / vbmeta** | ✅ | **custom AVB key** (`avb_custom_key`) makes the owner the root of trust for these |
|
||||
| Android userspace (adb, settings) | ✅ | root / WRITE_SECURE_SETTINGS |
|
||||
|
||||
**Key consequence:** you can become the verified-boot root of trust for
|
||||
everything from `boot` upward, but **not** for the bootloader itself. So a
|
||||
legitimately-signed, password-patched `fastboot` is impossible — the only way to
|
||||
run modified ABL code is an exploit (see §5, §8).
|
||||
|
||||
## 5. Cryptographic reality (for the record)
|
||||
- RSA-2048/4096 and ECDSA P-256 are **not broken** by any known classical
|
||||
attack. Bootloader signing keys are in this range → **not forgeable.**
|
||||
- What *is* real: factored **weak** RSA (≤829-bit, academic), **ECDSA nonce
|
||||
reuse / bad RNG** (PS3, Bitcoin — implementation, not algorithm), **side-channel
|
||||
/ fault-injection** bypasses of the *verification path*, and **future quantum**
|
||||
(Shor's — no cryptographically-relevant quantum computer exists yet; NIST PQC
|
||||
migration is pre-emptive).
|
||||
- **Therefore:** defeating verified boot means attacking the *check*
|
||||
(glitch / memory-corruption bug in the verifier or command parser), **not**
|
||||
breaking the *key*. This is the premise of the research track (§8).
|
||||
|
||||
## 6. Defensive architecture — achievable, layered
|
||||
Ordered so each layer builds on the one below it.
|
||||
|
||||
- **L0 — Foundation: custom AVB root of trust + re-lock.**
|
||||
Generate an owner AVB key; build a **KSU-integrated** GKI `boot` image (baked
|
||||
in, not LKM, so root survives lock); build a custom recovery; sign
|
||||
boot/init_boot/vendor_boot/recovery/vbmeta with the owner key;
|
||||
`fastboot flash avb_custom_key`; flash; **prove it boots**; then
|
||||
`fastboot flashing lock`. *Delivers:* locked verified boot **with** root; ABL
|
||||
fastboot becomes crypto-inert (refuses flash/boot/erase/unlock); recovery
|
||||
cannot be swapped. **This is the linchpin — every other layer depends on it.**
|
||||
|
||||
- **L1 — Password-gated recovery.** Compile a secret gate into the signed
|
||||
recovery ramdisk for the pre-decryption actions: **fastbootd**, ADB sideload,
|
||||
factory reset. (fastbootd *is* "fastboot from inside recovery" — the piece the
|
||||
owner actually controls.)
|
||||
|
||||
- **L2 — USB-when-locked cutoff + adb hard-off.** Deny USB data/enumeration
|
||||
(charge-only) whenever the screen is locked — the single most Cellebrite-
|
||||
relevant control (GrapheneOS's headline feature). Implement as a kernel module
|
||||
(reuses the CellGuard build pipeline) or a root daemon on keyguard state.
|
||||
adb defaults **off**; enabling is biometric/PIN-gated with an auto-off timeout.
|
||||
|
||||
- **L3 — Auto-reboot to BFU.** Root/KSU daemon reboots after N minutes locked,
|
||||
evicting in-RAM keys → forces the hard BFU state, defeating AFU extraction.
|
||||
|
||||
- **L4 — Duress / honeypot.** Only meaningful once L0 is locked (else the
|
||||
attacker boots their own image and skips it). Options:
|
||||
- **Non-destructive decoy** — a duress credential boots a sterile decoy user
|
||||
while the real user's keys stay underived.
|
||||
- **Destructive** — duress credential (or repeated failures) evicts/wipes the
|
||||
real keys.
|
||||
- **Boot-context branch** — `init` inspects `androidboot.bootreason`/mode and
|
||||
presents the decoy on abnormal boot.
|
||||
- *Limit:* true deniability is weak on Android — FBE metadata reveals that
|
||||
multiple users/volumes exist. Destructive duress is more reliable than a
|
||||
deniable-hidden-volume approach.
|
||||
|
||||
- **L5 — Strong passphrase** (owner action). Converts lockscreen brute force
|
||||
from "time + exploit" into a non-starter.
|
||||
|
||||
## 7. Honest limits (what will NOT work, and why)
|
||||
- **Patching/signing ABL** — bootrom-anchored to the OEM key; a modified
|
||||
bootloader can't be signed and won't boot. Only an *exploit* runs it (§8).
|
||||
- **Hiding/redirecting the ABL fastboot key-combo** — the key combo is read by
|
||||
the signed bootloader *before* any OS/recovery code; recovery can't intercept
|
||||
it. The "TWRP forces you through recovery" trick (e.g., on the S20) relies on
|
||||
a more malleable bootloader and the fact that Samsung has **no fastboot**
|
||||
(Download/Odin + Knox instead). Not reproducible on Tensor.
|
||||
- **Deniable hidden volumes** — FBE leaks the existence of multiple data sets.
|
||||
- **Current unlocked bootloader** — negates most in-OS defenses until L0 re-lock,
|
||||
because an attacker can just boot their own image.
|
||||
|
||||
## 8. Research track — ABL vulnerability research (authorized, own device)
|
||||
Parallel to the defensive build. Premise (§5): attack the verification, not the
|
||||
key. Assets already on hand: the **`rango` factory image** in
|
||||
`~/PixelFlasher/dist/` (contains `bootloader-rango-*.img`) and existing **Ghidra**
|
||||
projects under `seteclabs/rango-wifi-monitor`.
|
||||
|
||||
1. **Unpack** `bootloader-rango-*.img` → split the pack into stages
|
||||
(bl1/bl2/bl31/pbl/ABL; Tensor uses a Samsung-style chain).
|
||||
2. **Load ABL into Ghidra**; locate the fastboot dispatch (strings: `getvar`,
|
||||
`download:`, `flash:`, `boot`, `oem `, `reboot-bootloader`).
|
||||
3. **Audit the parser** for classic wins: unchecked lengths in
|
||||
`download`/sparse-image handling, `oem` vendor commands (least-audited
|
||||
surface), integer overflows in partition sizing.
|
||||
4. **Firmware diffing** across bootloader versions — patched bugs point at the
|
||||
interesting code and sometimes yield n-days.
|
||||
5. **Hardware surface** (if pursued): identify UART/JTAG test points; assess the
|
||||
voltage/EM **glitch** surface on the signature-check path (ChipWhisperer-class).
|
||||
|
||||
*Strategic note:* an ABL exploit is the attacker's own primitive and is fragile
|
||||
(breaks/needs rework each firmware update). It should **not gate** the defensive
|
||||
build — ship L0–L3 for protection now, run the RE track in parallel.
|
||||
|
||||
## 9. Safety rig / escape hatch (mandatory before anything irreversible)
|
||||
- Keep the **factory image `flash-all`** ready (`~/PixelFlasher/dist/`).
|
||||
- Keep the bootloader **unlocked** and **OEM-unlocking enabled** until the signed
|
||||
chain is proven to boot cleanly.
|
||||
- **Dry-run the full sign → flash → boot cycle unlocked first**; confirm
|
||||
`avbtool verify` passes against the owner key **before** ever typing
|
||||
`fastboot flashing lock`.
|
||||
- `flashing lock` is the **last** step; disable OEM-unlocking only after the
|
||||
locked chain is proven stable.
|
||||
- Prefer proving the sign/lock/escape-hatch loop on a **spare** device before the
|
||||
daily driver.
|
||||
|
||||
## 10. Risk register
|
||||
| Risk | Mitigation |
|
||||
|---|---|
|
||||
| Re-lock with a non-verifying image → hard brick | dry-run unlocked; `avbtool verify`; keep OEM-unlock until proven |
|
||||
| OTA breaks the owner-signed chain | re-sign after each update; hold OTAs until pipeline is scripted |
|
||||
| KSU integration regressions under lock | validate root + boot on unlocked build first |
|
||||
| Duress deniability weaker than hoped | prefer destructive duress; document the limit |
|
||||
| Losing the working session over wireless adb when disabling adb | attach USB fallback before testing the "off" path |
|
||||
|
||||
## 11. Roadmap / next actions
|
||||
- **Phase 0:** prove the escape hatch (spare device and/or verified factory flash).
|
||||
- **Phase 1 (reversible):** L0 foundation — AVB key + KSU-integrated signed boot;
|
||||
flash and boot **unlocked** to validate; do **not** lock yet.
|
||||
- **Phase 2:** L1 recovery gate + L2 USB-when-locked / adb hard-off.
|
||||
- **Phase 3:** L3 auto-reboot-to-BFU + L4 duress/honeypot; then L0 `flashing lock`.
|
||||
- **Parallel:** §8 ABL RE track (unpack `bootloader-rango-*.img` → Ghidra).
|
||||
|
||||
---
|
||||
|
||||
## Appendix A — current-state levers (verified this session)
|
||||
```
|
||||
settings get global adb_enabled -> 1 (USB debugging)
|
||||
settings get global adb_wifi_enabled -> 1 (wireless debugging; current link)
|
||||
getprop ro.adb.secure -> 1 (RSA host-key auth enforced)
|
||||
/data/misc/adb/adb_keys -> 1 authorized host key
|
||||
```
|
||||
adb kill switch: `settings put global adb_enabled 0; settings put global
|
||||
adb_wifi_enabled 0; setprop ctl.stop adbd`.
|
||||
|
||||
## Appendix B — related work in this project
|
||||
- `common/kmod/cellguard.c` — kernel module; demonstrates the GKI build + load
|
||||
path (protected-symbol resolution via kallsyms) reused by L2.
|
||||
- `common/kmod/build-stock-gki.sh` — stock-GKI module build pipeline; the basis
|
||||
for building the L0 KSU-integrated signed boot image.
|
||||
203
common/docs/cellguard-dossier.md
Normal file
203
common/docs/cellguard-dossier.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# CellGuard — Project Dossier (rango / Pixel 10 Pro Fold)
|
||||
|
||||
Kernel-enforced cellular security for a stock-GKI Pixel: block 2G/3G + weak/null
|
||||
ciphers, force LTE/5G-SA, detect IMSI-catchers/stingrays. This dossier records
|
||||
everything established so far — device facts, the solved build/load problem, the
|
||||
reverse-engineered modem control path, and the detection/blocking architecture.
|
||||
|
||||
---
|
||||
|
||||
## 1. Device baseline
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Device | Pixel 10 Pro Fold, `rango`, Tensor G5 (`laguna`) |
|
||||
| Modem | Samsung **Shannon S5400** via **cpif/PCIe** (no UART AT) |
|
||||
| Kernel | stock GKI `6.6.102-android15-8-g6eb5b2a8c46b-ab14739656-4k` |
|
||||
| Kernel cfg | RANDSTRUCT_NONE, CFI_CLANG (strict), MODVERSIONS, LTO_NONE, **MODULE_SIG_PROTECT**, MODULE_SIG_FORCE **off**, KPROBES=y |
|
||||
| Root | KernelSU **LKM** |
|
||||
| Bootloader | unlocked (props spoofed locked/green) |
|
||||
| RIL | `/vendor/bin/hw/rild_exynos` + `libsitril*` (SIT protocol) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Kernel module build & load — **SOLVED**
|
||||
|
||||
### Root cause of the original failures
|
||||
1. **`Exec format error`** — the shipped `cellguard.ko` was built against a
|
||||
**GrapheneOS** `laguna` kernel tree (`6.6.129`, `RANDSTRUCT_FULL`). Under
|
||||
MODVERSIONS the kernel ignores the release string but compares the vermagic
|
||||
**flag suffix** + symbol CRCs; the RANDSTRUCT flag and mismatched CRCs
|
||||
(`module_layout` etc.) → `ENOEXEC`.
|
||||
2. **`Protected symbol: kernel_write/kernel_read (-13)`** — stock GKI
|
||||
`MODULE_SIG_PROTECT` lets unsigned modules load but forbids importing a
|
||||
protected symbol subset. `kernel_read`/`kernel_write` are protected.
|
||||
|
||||
### Fix
|
||||
- **Build against stock GKI**, not Graphene: cloned `kernel/common` at the exact
|
||||
build SHA `6eb5b2a8c46b`, used the device's real `/proc/config.gz`, and the
|
||||
build's `vmlinux.symvers` (real CRCs). Native Debian **clang 19** (kCFI
|
||||
type-IDs are ABI-stable across clang versions). Result vermagic flags +
|
||||
all 49 harvestable CRCs (incl. `module_layout 0x4e276f37`) match the device.
|
||||
- **Resolve protected symbols at runtime**: `cellguard.c` now bootstraps
|
||||
`kallsyms_lookup_name` via a one-shot **kprobe** (`cg_lookup_name`) and calls
|
||||
`kernel_read`/`kernel_write` through pointers (`cg_kernel_read/write`,
|
||||
`cg_resolve_protected`). Zero protected symbols imported → loads unsigned, and
|
||||
is **portable across all stock android15/6.6 GKI devices** (KMI-frozen imports).
|
||||
|
||||
### Result
|
||||
`insmod` succeeds; `/dev/cellguard` (major 475) + `/proc/cellguard/status` live;
|
||||
module inert by default. Confirmed loaded via the KSU module path
|
||||
(`/data/adb/modules/cellguard/common/kmod/cellguard.ko`, loaded by `service.sh`).
|
||||
|
||||
### Artifacts
|
||||
- `common/kmod/cellguard.ko` — working stock-GKI build (sha256 `676ee6d1…`)
|
||||
- `common/kmod/cellguard.ko.badvermagic` — old broken build (backup)
|
||||
- `common/kmod/build-stock-gki.sh` — reproducible pipeline (auto-detects build,
|
||||
downloads GKI artifacts, clones exact source, builds)
|
||||
- `common/kmod/device.config` — offline config fallback
|
||||
|
||||
---
|
||||
|
||||
## 3. Modem control path — reverse-engineered (cpif / SIPC5)
|
||||
|
||||
**Key finding: rango exposes NO AT tty.** The DT `iodevs` node has no
|
||||
`umts_atc*`/`nr_atc*`; `cpif.ko` contains zero AT strings and no AT parser. Both
|
||||
`cellguard.c` and RadioControl's `rc_shannon_cmd.c` assume an AT tty that does
|
||||
not exist — they only ever opened `/dev/umts_router` (a RAW relay) by luck, where
|
||||
`AT+…` bytes become an opaque SIPC5 payload the modem ignores.
|
||||
|
||||
Channel names are **not in the driver** — `cpif` reads them from the device tree
|
||||
(`parse_dt_iodevs_pdata`). Extracted from the decompiled DTB (dtbo → `iodevs`):
|
||||
|
||||
### rango channel map (DT `iodevs`, enums proven vs `cpif.ko`)
|
||||
| /dev node | iod,ch | format | io_type | attrs | role |
|
||||
|---|---|---|---|---|---|
|
||||
| `umts_ipc0/1` | 0xf5 | FMT | MISC | 0x6000 | primary control — **held by RIL** |
|
||||
| **`oem_ipc0..7`** | **0x81** | **FMT** | MISC | 0x2000 | **OEM/SIT control (best for us)** |
|
||||
| `oem_test` | 0x89 | RAW | MISC | 0 | OEM test sink |
|
||||
| `umts_router` | 0x15 | RAW | MISC | 0 | opaque relay (no command parser) |
|
||||
| `umts_dm0` | 0x51 | RAW/DIAG | MISC | 0x4000 | **CP diagnostic egress (detection)** |
|
||||
| `rmnet` | 0xb5 | RAW | NET | 0x2000 | packet data (30 ch) |
|
||||
| `umts_rfs0` | 0x29 | RAW | MISC | 0 | remote fs |
|
||||
| `umts_boot0` | 0xf1 | BOOT | BOOTDUMP | 0x4200 | modem boot/flash |
|
||||
| `umts_rcs0/1`,`umts_wfc0/1`,`gnss_*`,`esim_tracer` | … | … | … | … | misc |
|
||||
|
||||
Enum decodings (proven in `cpif.ko`): `iod,format {0=FMT,1=RAW,3=MULTI_RAW,4=BOOT}`;
|
||||
`iod,io_type {0=BOOTDUMP,1=MISC(char dev),2=NET,3=DUMMY}` (jump table
|
||||
`sipc5_init_io_device` @0xce78); `attrs` bit8 `0x100`=NO_LINK_HEADER,
|
||||
bit13 `0x2000`=MULTI_CHANNEL.
|
||||
|
||||
### Framing contract — **PROVEN** from `cpif.ko` (non-stripped)
|
||||
cpif frames/deframes **SIPC5 itself**; userspace exchanges **bare payloads**:
|
||||
- **TX** `ipc_write@0x1ad8`: `_copy_from_user` the buffer verbatim as payload,
|
||||
`skb_push(4)`, then `sipc5_build_config@0xccc8` (config base **0xF8**) +
|
||||
`sipc5_build_header@0xcd80` (`hdr[1]=iod,ch` from DT). On the wire a small
|
||||
frame = **`F8 <ch> <u16 len LE> <payload>`**. The channel byte + header come
|
||||
from the kernel — **never prepend your own**.
|
||||
- **RX** `rx_fmt_ipc@0xd87c` / `rx_raw_misc@0xdde0`: `skb_pull` the SIPC5 header,
|
||||
queue bare payload to `iod->rxq (+0x138)`; `ipc_read@0x18c4` returns **bare
|
||||
binary payload** (no `\r\n`, no `OK/ERROR`).
|
||||
- FMT channels carry a 7-bit transaction id (`sipc5_build_config` @0xcd60) →
|
||||
request/reply correlation. RAW channels don't (why `oem_ipc` FMT beats
|
||||
`umts_router` RAW for control).
|
||||
|
||||
### Corrected driver design (proposed patch, not yet applied)
|
||||
- `modem_paths[]` → `{umts_dm0, oem_ipc, umts_router}` (drop nonexistent AT ttys)
|
||||
- `at_cmd()` → bare-payload I/O; **no** CRLF, **no** OK/ERROR scan
|
||||
- add `sit_tx_enabled` gate, **default false** = passive/read-only, **zero
|
||||
baseband TX** (honors the modem-sensitivity rule)
|
||||
- same fix for `rc_shannon_cmd.c`; note it also needs the kprobe/kallsyms
|
||||
bootstrap before it can load on stock GKI
|
||||
|
||||
---
|
||||
|
||||
## 4. IMSI-catcher detection + band blocking — architecture
|
||||
|
||||
Maximum control = a kernel module at the **cpif SIPC5 layer**, three stacked
|
||||
capabilities:
|
||||
|
||||
1. **Detection — DIAG (`umts_dm0`, ch 0x51), passive/read-only.** CP diagnostic
|
||||
stream carries layer-3 (RRC/NAS), cell measurements, cipher/auth params,
|
||||
paging. Flag: forced 2G/3G downgrade, null/weak cipher (A5/0, EEA0/NEA0),
|
||||
IMSI/IMEI identity requests, silent paging/SMS, abnormal cell (LAC/TAC without
|
||||
handover, MCC/MNC mismatch, implausible signal), skipped AKA. Reference:
|
||||
**P1sec SCAT** parses Samsung/Shannon DM.
|
||||
2. **Blocking — SIT over `oem_ipc` 0x81 / `umts_ipc` 0xf5 (FMT).**
|
||||
`SET_ALLOWED_NETWORK_TYPE` → LTE+NR only; band-lock; null-cipher-off. Needs
|
||||
the SIT opcodes (RE in progress).
|
||||
3. **Max control — kprobe-hook `cpif`** (symbols in kallsyms): hook RX
|
||||
(`rx_fmt_ipc`,`rx_raw_misc`) to see *all* AP↔CP frames; hook TX
|
||||
(`ipc_write`/`sipc5_build_header`) to **veto/rewrite** commands so 2G/3G can't
|
||||
be re-enabled behind us — a baseband IDS/firewall at the driver boundary.
|
||||
|
||||
Build order: (1) passive DIAG detector now → (2) SIT blocking after opcode RE →
|
||||
(3) cpif kprobe hooks.
|
||||
|
||||
---
|
||||
|
||||
## 5. SIT / DIAG RE — in progress
|
||||
Pulled read-only to `/home/snake/re/`: `rild_exynos`, `libsitril.so`,
|
||||
`libril_sitril.so`, `libsit_oem.so`, `libsit_oem_proto.so`,
|
||||
`libsitril-client.so`, `vendor.radio.protocol.sit.{base,stream}.so`.
|
||||
|
||||
Control handlers confirmed in `libsitril.so` strings:
|
||||
- RAT: `NETWORK_TYPE_BITMAP_LTE_ONLY` / `_LTE_WCDMA` / `_GSM_ONLY` …
|
||||
(setAllowedNetworkType)
|
||||
- Band: `DoSetBandMode` / `DoSetManualBandMode` / `DoQueryAvailableBandMode`
|
||||
- Cipher: `IsNullCipherAndIntegrityEnabledHandler` (+ Set)
|
||||
|
||||
**Fable RE workflow running** (`rango-sit-diag-re`) to extract: the on-wire SIT
|
||||
frame layout (`vendor.radio.protocol.sit.stream.so`), the main/sub command IDs +
|
||||
param encoding for RAT/band/cipher, and the Shannon DM/DIAG record framing (SCAT).
|
||||
Output: SIT encoder spec + DIAG parser spec + proposed cellguard code blocks.
|
||||
|
||||
---
|
||||
|
||||
## 6. Toolchain & artifact locations
|
||||
| What | Where |
|
||||
|---|---|
|
||||
| cellguard source | `/home/snake/CellGuard/common/kmod/cellguard.c` |
|
||||
| build pipeline | `/home/snake/CellGuard/common/kmod/build-stock-gki.sh` |
|
||||
| stock kernel src (KDIR) | scratchpad `src/common` (@ SHA `6eb5b2a8c46b`) |
|
||||
| cpif driver (RE, non-stripped) | scratchpad `re/cpif_factory.ko` |
|
||||
| decompiled DT | scratchpad `re/alldts.txt` (`iodevs` @ line 4911) |
|
||||
| SIT/RIL binaries | `/home/snake/re/` |
|
||||
| Ghidra | `/home/snake/tools/samsung-dev/ghidra_12.0.4_PUBLIC/` (headless in `support/`) |
|
||||
| RadioControl twin module | `/home/snake/RadioControl/common/kmod/rc_shannon_cmd.c` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Constraints (standing rules)
|
||||
- **No device ops (adb/insmod/push) without explicit per-action permission.**
|
||||
- **Never TX to the baseband without consent** — malformed OEM/FMT frames can
|
||||
reset the modem; `setenforce` also bounces RIL. Default builds are passive.
|
||||
- No AI attribution in any code/output. No stubs. `/home/snake` not `/tmp`
|
||||
(Pi `/tmp` is RAM). Surgical edits, one change at a time.
|
||||
|
||||
---
|
||||
|
||||
## 8. Next steps
|
||||
1. Finish SIT/DIAG RE (workflow) → SIT encoder + DIAG parser specs.
|
||||
2. Apply the corrected-channel/framing patch (passive/read-only default) →
|
||||
rebuild → load via KSU path.
|
||||
3. Add the Shannon-DIAG detector (SCAT-derived) → real IMSI-catcher detection.
|
||||
4. After opcode verification, gate-enable SIT blocking (RAT/band/cipher).
|
||||
5. Optional: cpif kprobe RX/TX hooks for full monitor + veto enforcement.
|
||||
6. Port `rc_shannon_cmd.c` to the same I/O layer + kallsyms bootstrap.
|
||||
|
||||
## 9. Backlog (deferred)
|
||||
- **IMSI-paging blocker (toggle).** No exposed modem command suppresses IMSI-paged
|
||||
responses (paging is baseband-autonomous). Buildable tiers:
|
||||
1. Force **IMSI/SUPI encryption** via SIT `DoSetCarrierInfoImsiEncryption`
|
||||
(stops IMSI harvesting at the source) — available command, needs capture/verify.
|
||||
2. **Detect + react**: flag IMSI paging from captured frames → toggle triggers
|
||||
detach / RAT-relock / alert.
|
||||
3. **True suppression**: modem.bin firmware patch to drop IMSI-paged responses
|
||||
(deep, risky — separate effort).
|
||||
|
||||
- **Full modem diagnostic-features access** (interactive DIAG/engineering mode,
|
||||
band control, signaling readouts) is a **separate app** (RadioControl scope),
|
||||
not CellGuard. CellGuard's raw CP-frame capture (`cgcap`) exists only to feed
|
||||
detection.
|
||||
|
||||
Related: device anti-forensics hardening plan → `docs/anti-forensics-hardening.md`.
|
||||
Reference in New Issue
Block a user