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:
sssnake
2026-07-12 09:21:54 -07:00
commit 9a3e3a0501
27 changed files with 3289 additions and 0 deletions

70
ratlock.sh Executable file
View File

@@ -0,0 +1,70 @@
#!/system/bin/sh
# CellGuard ratlock — hold every active SIM to LTE + 5G(NR) only.
#
# Anti-downgrade enforcement. A modem restricted to LTE+NR will not attach to
# any 2G/3G cell, including a cell-site simulator attempting a downgrade. We use
# the platform telephony API (setAllowedNetworkTypesForReason, USER reason),
# which is applied by rild to the modem — no raw baseband injection needed.
#
# NR = 5G (both NSA and SA). 5G-SA is allowed and preferred.
#
# Mask (TelephonyManager NetworkTypeBitmask, binary form):
# LTE(bit12) | LTE_CA(bit18) | NR(bit19) = 0xC1000 = 11000001000000000000
CG_DIR="/data/adb/cellguard"
LOG="$CG_DIR/ratlock.log"
MASK_BIN="11000001000000000000" # LTE | LTE_CA | NR
POLL="${1:-5}" # seconds between checks
mkdir -p "$CG_DIR"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG"; }
# Active voice/data slots (phoneId where a subscription is IN_SERVICE-capable).
active_slots() {
# slots 0..3; a slot is active if get-allowed returns a value (has a sub)
for s in 0 1 2 3; do
v=$(cmd phone get-allowed-network-types-for-users -s "$s" 2>/dev/null)
case "$v" in
*LTE*|*NR*|*GSM*|*WCDMA*) echo "$s" ;;
esac
done
}
apply() { # $1 = slot
cmd phone set-allowed-network-types-for-users -s "$1" "$MASK_BIN" >/dev/null 2>&1
}
# A downgrade attempt = any allowed RAT below LTE (GSM/WCDMA/TDSCDMA/CDMA present).
downgraded() { # $1 = current allowed-types string
case "$1" in
*GSM*|*GPRS*|*EDGE*|*WCDMA*|*HSPA*|*UMTS*|*TD_SCDMA*|*CDMA*|*EVDO*) return 0 ;;
*) return 1 ;;
esac
}
PERMISSIVE="11111111111111111111" # all RATs (framework filters to modem-supported)
apply_all() { cmd phone set-allowed-network-types-for-users -s "$1" "$PERMISSIVE" >/dev/null 2>&1; }
# The "Block 2G/3G" WebUI toggle writes $CG/enabled (1=on). Default on.
enabled() { [ "$(cat "$CG_DIR/enabled" 2>/dev/null)" != "0" ]; }
log "ratlock start (poll=${POLL}s)"
# watchdog loop: while ON, hold LTE+NR and re-assert on any 2G/3G reintroduction;
# while OFF, restore full RAT so 2G/3G work again.
while true; do
for s in $(active_slots); do
cur=$(cmd phone get-allowed-network-types-for-users -s "$s" 2>/dev/null)
if enabled; then
if downgraded "$cur"; then
log "slot $s DOWNGRADE (allowed=$cur) -> re-asserting LTE+NR(5G)"
apply "$s"
fi
else
# disabled: if still locked, restore permissive once
if ! downgraded "$cur"; then
apply_all "$s"; log "slot $s protection OFF -> restored all RAT"
fi
fi
done
sleep "$POLL"
done