Pixel 9 — Mobile Security Research Setup
📱 Pixel 9 — Mobile Security Research Setup
This guide is for authorized red team engagements and security research only. Unlocking bootloaders and rooting voids warranty. NAS/protocol testing must be performed within engagement scope and applicable law. Never test against live networks without explicit written authorization.
Hardware Reality Check — Tensor G4 vs Qualcomm
This changes your toolchain significantly. Many telecom research tools (SCAT, QXDM) target Qualcomm modems only.
graph LR
subgraph "Pixel 9 — Tensor G4"
T1["Google Tensor G4 SoC"]
T2["Samsung Exynos\nModem 5400"]
T3["Diagnostic: Samsung\nDiag protocol — partial\nSCAT support (limited)"]
end
subgraph "Qualcomm Devices (Better for NAS Research)"
Q1["Snapdragon 8 Gen 3"]
Q2["Qualcomm X75 Modem"]
Q3["SCAT full support\nQXDM · QPST · full\nNAS decode"]
end
subgraph "Pixel 9 Capabilities"
C1["✅ Bootloader unlock\nsupported"]
C2["✅ Magisk root\nfull support"]
C3["✅ ADB modem\ndiagnostic access"]
C4["✅ NAS state\nmanipulation via\ncustom RIL/AT cmds"]
C5["⚠️ Full NAS decode\nlimited vs Qualcomm"]
C6["✅ UERANSIM\nclient mode\nvia Termux + USB"]
end
style T2 fill:#E36209,color:#fff
style Q3 fill:#1F3864,color:#fff
style C1 fill:#2E75B6,color:#fff
style C5 fill:#E36209,color:#fffBottom line: Pixel 9 is excellent for app-layer, API, and subscriber-identity testing. For deep NAS packet capture, pair it with a Qualcomm-based second device or use UERANSIM on a laptop connected via the Pixel 9's hotspot.
Setup Flow
flowchart TD
A["🛒 Start: Pixel 9\nAndroid 15"] --> B["⚙️ Phase 1\nDeveloper Mode &\nADB Setup"]
B --> C{"Device Type?"}
C -->|"Telecom-Joined\n(MDM enrolled — this setup)"| D1["🔒 Phase 3\nNo-Root Path\nNetHunter Rootless"]
C -->|"Clean Device\n(unlocked from Google Store)"| E["🔓 Phase 2\nBootloader Unlock"]
E --> F["🪄 Phase 3A/B\nMagisk Root\nor GrapheneOS"]
D1 --> G["📦 Phase 4\nCore Tool Install\nTermux · Frida Rootless · HTTP Toolkit"]
F --> G
G --> H["📡 Phase 5\nModem Diagnostic\nSetup"]
H --> I["🧪 Phase 6\nTesting Validation\n& Capability Check"]
style A fill:#1F3864,color:#fff
style C fill:#E36209,color:#fff
style D1 fill:#2E75B6,color:#fff
style F fill:#C00000,color:#fff
style I fill:#2E75B6,color:#fffThis guide is written for a telecom-joined Pixel 9 (carrier MDM enrolled). The primary path skips bootloader unlock entirely. The Magisk and GrapheneOS paths are documented for reference — they apply to a second, clean unlocked device. See Device Strategy at the end.
Do you need Phase 3 and 3A?
No. Treat them as alternative paths, not sequential required steps.
| Situation | Necessary path |
|---|---|
| This current telecom-joined Pixel 9 | Phase 3 |
| Second clean unlocked Pixel for root-only testing | Phase 3A |
| You only need app testing, ADB telecom inspection, cell info, and non-destructive workflow | Phase 3 only |
You need system cert injection, full Frida, full tcpdump, or deeper modem access |
Add Phase 3A on a separate device |
Phase 1 — Developer Mode & ADB
# On Pixel 9:
# Settings → About Phone → Build Number (tap 7x) → Developer Options enabled
# Enable in Developer Options:
# ✅ USB Debugging
# ✅ OEM Unlocking ← required before bootloader unlock
# ✅ Wireless Debugging (for wireless ADB)
# On your workstation:
adb devices # verify device recognized
adb shell getprop ro.product.model # should return "Pixel 9"
adb shell getprop ro.build.version.release # Android version
adb shell getprop gsm.version.baseband # modem firmware version
Phase 2 — Bootloader Unlock
# Reboot to bootloader
adb reboot bootloader
# Verify fastboot sees device
fastboot devices
# Unlock bootloader (requires OEM unlock enabled in Developer Options)
fastboot flashing unlock
# Device will show warning → use volume keys to confirm → power to accept
# Device wipes and reboots → re-enable Developer Options + USB debugging
If purchased from a carrier (Verizon, AT&T, T-Mobile), OEM unlock may be grayed out for 60-180 days or permanently disabled. Always buy unlocked directly from Google Store for research devices.
Phase 3 — No-Root Path (Telecom-Joined Device — This Setup)
This Pixel 9 is carrier MDM-enrolled. Bootloader unlock triggers Play Integrity failure → MDM detects it and may wipe/lock the device. You also lose the carrier SIM binding that makes this device valuable. Verify MDM status first.
Phase 3 is the necessary path for the current telecom-joined device. If this is the handset you are actually carrying into an engagement, stop here and build your workflow around the no-root path.
# Check if OEM unlock is available:
# Settings → Developer Options → OEM Unlocking
# If GREYED OUT → MDM is active. Stop here. Use the no-root path.
# Verify MDM enrollment:
adb shell dumpsys device_policy | grep -i "admin\|mdm\|enrolled"
adb shell pm list packages | grep -i "mdm\|dpc\|enterprise"
NetHunter Rootless — Kali Tools Without Any OS Change
# NetHunter Rootless runs a full Kali chroot inside Termux — no root needed.
# Official guide: https://www.kali.org/docs/nethunter/nethunter-rootless/
# Step 1: Install Termux from F-Droid (NOT Google Play)
# Step 2: Install NetHunter Store APK from:
# https://store.nethunter.com/
# Step 3: From NetHunter Store → install:
# • Kali NetHunter App
# • KeX (Kali desktop if needed)
# Step 4: Open NetHunter app → install Kali chroot (rootfs download ~1GB)
# You now have a full Kali CLI:
# kali ← launches Kali shell in NetHunter app
# Inside Kali: apt install <any-kali-tool>
Capability map — no-root Pixel 9:
| Capability | Available | Method |
|---|---|---|
| Kali toolchain | ✅ | NetHunter Rootless chroot |
| ADB modem diagnostics | ✅ | dumpsys telephony, dumpsys phone |
| Cell info harvesting | ✅ | NetMonster, dumpsys telephony.registry |
| App-layer MITM | ✅ (non-pinned apps) | HTTP Toolkit or Packet Capture VPN app |
| Frida hooks | ⚠️ Limited | Rootless attach (user procs) or frida-gadget APK repack |
| Burp CA injection | ⚠️ User cert only | Works for non-pinned apps; not system store |
| Network scanning | ✅ | Termux nmap, tshark |
| AT command access | ⚠️ Partial | ADB shell debug paths |
| Burp CA → system store | ❌ | Needs root |
| Frida on system/carrier apps | ❌ | Needs root |
| tcpdump all interfaces | ❌ | Needs root |
| Full modem diag port | ❌ | Needs root |
If this is your only device, what do you lose?
If you stay on the safe Phase 3-only path, you do not lose the core value of the phone for telecom research. You still keep:
- real carrier / MDM context
- genuine SIM and subscriber identity testing
- ADB-based telephony inspection
- cell information harvesting
- non-destructive app-layer interception against easier targets
What you do lose is the deeper root-only layer:
- full MITM against pinned or system-trust-only apps
- Frida against carrier apps, privileged apps, and system processes without repackaging
- full-device packet capture with
tcpdump -i any - cleaner modem / diag / AT access
- system trust-store injection
- easier LSPosed/Xposed-style hooking
Since you only have one device, the practical tradeoff is simple: you keep the authentic carrier handset use case, but give up the destructive or root-heavy research use case unless you later add a second clean unlocked device.
Phase 3A — Magisk Root on Stock Android (Clean Device Only)
Do NOT attempt this on the telecom-joined Pixel 9. This path is for a second device purchased unlocked directly from the Google Store and never enrolled in a carrier/corporate MDM.
Phase 3A is optional. Use it only when you have a separate clean unlocked device and you specifically need root-only capabilities such as system trust-store injection, full Frida coverage, full-interface packet capture, or deeper modem access.
Where patched_init_boot.img comes from
You do not download patched_init_boot.img directly.
Use this flow:
- Download the official Google Pixel 9 factory image or full OTA for the exact build currently on the phone
- Extract the stock
init_boot.imgfrom the matching factory image - Copy
init_boot.imgto the Pixel - Patch it in Magisk
- Copy the resulting
patched_init_boot.imgback to your laptop - Flash that patched image with
fastboot
Match the image to your exact current build number from:
adb shell getprop ro.build.fingerprint
or
adb shell getprop ro.build.id
Do not patch a random Pixel 9 image from a different monthly build.
Official sources
- Factory images:
https://developers.google.com/android/images - Full OTA packages:
https://developers.google.com/android/ota
Practical guidance
- Easiest path for Magisk boot patching: use the factory image for your exact build, because it gives you a direct route to
init_boot.img - OTA path: works too, but often requires extracting from
payload.bin, which is more annoying - On modern Pixels such as the Pixel 9 (
tokay), Magisk root is obtained by patchinginit_boot.img, notboot.img
flowchart LR
A["Download stock\nPixel 9 factory image\nfrom Google"] --> B["Extract init_boot.img\nfrom factory zip"]
B --> C["Copy init_boot.img\nto Pixel 9 storage"]
C --> D["Install Magisk APK\non device"]
D --> E["Magisk → Install\n→ Select init_boot.img\n→ Patch"]
E --> F["Copy patched_init_boot.img\nback to workstation"]
F --> G["fastboot flash init_boot_\npatched_init_boot.img"]
G --> H["✅ Rooted Pixel 9\nStock Android preserved"]
style H fill:#2E75B6,color:#fff # On laptop: identify current build first
adb shell getprop ro.build.id
adb shell getprop ro.build.fingerprint
adb shell getprop ro.boot.slot_suffix
# Download the matching official Pixel 9 image from Google
# Then extract init_boot.img from the factory image package
# Copy stock init_boot.img to the phone
adb push init_boot.img /sdcard/Download/
# On the phone:
# Open Magisk → Install → Select and Patch a File → choose /sdcard/Download/init_boot.img
# Magisk writes a patched image, typically under /sdcard/Download/
# List the patched file first; quote the remote wildcard so your local shell does not expand it
adb shell 'ls -lt /sdcard/Download/magisk_patched*.img'
# Pull the exact patched image back to the laptop
adb pull /sdcard/Download/magisk_patched-<id>.img patched_init_boot.img
# Reboot from Android into the bootloader
adb reboot bootloader
fastboot devices
# Flash patched init_boot to the active slot
# Example: if ro.boot.slot_suffix returned _b, flash init_boot_b
fastboot flash init_boot_<slot> patched_init_boot.img
fastboot reboot
# Verify root
adb shell su -c "id" # should return uid=0(root)
# Recommended Magisk modules for research:
# • MagiskHide / Shamiko — hide root from banking/telco apps
# • LSPosed — Xposed framework for app hooking
# • MoveCA / TrustMeAlready — inject Burp CA into system store
Unlocks on a rooted clean device:
- Full Frida server (persistent, all processes)
- Burp CA in system trust store (works against all apps)
tcpdump -i any(capture all interfaces)- Full AT command access to modem (
/dev/ttyACM0) - LSPosed hooks on carrier/system apps
Phase 3B — GrapheneOS (Clean Device, OPSEC Focus)
GrapheneOS is the right call when OPSEC matters more than deep carrier API compatibility — e.g., you're researching what a privacy-hardened device leaks to carrier infrastructure, or you need near-zero telemetry during a physical red team where device seizure is possible. Trade-off: some carrier apps lose deep OS integration (VoLTE auto-config, RCS).
# Install via web installer at grapheneos.org/install/web
# Requires Chrome/Edge with WebUSB support — Pixel 9 is fully supported
# Post-install:
# Settings → System → Developer Options → enable ADB
# Install sandboxed Google Play for carrier app compatibility
# Note: some carrier provisioning flows need native Google Services —
# test per-carrier before using this as primary research platform
GrapheneOS vs Magisk for telecom research:
| Factor | Magisk (Stock) | GrapheneOS |
|---|---|---|
| RIL / AT command access | ✅ Native | ✅ Works |
| Carrier app deep integration | ✅ Full | ⚠️ Sandboxed |
| VoLTE / RCS provisioning | ✅ | ⚠️ May require workaround |
| Telemetry to Google | ⚠️ Present | ✅ Near-zero |
| Device seizure OPSEC | ⚠️ | ✅ Strong |
| Network fingerprint | Standard Pixel | Slightly hardened |
| Root access | ✅ Magisk | ⚠️ Root via ADB only |
Phase 4 — Core Tool Installation
Where Phase 4 actually happens
Phase 4 is split between your laptop and the Pixel, not done in only one place.
| Component | Where you do it |
|---|---|
Install desktop tooling like adb, frida-tools, Burp, HTTP Toolkit, jadx, MobSF helpers |
Laptop |
| Install Termux / NetHunter Rootless / target apps | Pixel 9 |
| Push, pull, inspect packages, and launch workflows | From laptop over ADB |
Run on-device CLI tools such as pkg, pip, termux-setup-storage |
Inside Termux on the Pixel |
Practical answer
Yes — you start Phase 4 from your laptop, but some steps finish on the phone itself.
Use this order:
- Laptop: connect ADB and verify the phone.
- Pixel: install Termux and any Android-side apps.
- Pixel / Termux: install the on-device packages.
- Laptop: use ADB, Frida, Burp, or HTTP Toolkit to drive the workflow.
# Laptop side
adb devices
adb shell getprop ro.product.model
# Install APKs from the laptop when needed
adb install termux.apk
adb install httptoolkit.apk
# Open a shell from the laptop
adb shell
# Then, inside Termux on the Pixel, run:
# pkg update && pkg upgrade
# pkg install python3 git curl wget nmap tcpdump openssl tshark netcat-openbsd dnsutils
# pip install scapy requests frida-tools impacket
# termux-setup-storage
Think of Phase 4 as laptop-orchestrated, phone-executed. Your laptop is the control station; the Pixel is where the Android and Termux-side tooling actually lives.
In this setup, keep the persistent Frida tooling on the laptop under ~/Documents/mobility/frida/:
- Server binary:
~/Documents/mobility/frida/frida-server - Client CLI:
~/Documents/mobility/frida/venv/bin/frida-ps - Interactive CLI:
~/Documents/mobility/frida/venv/bin/frida
4.1 Termux (Linux Environment on Device)
# Install from F-Droid (NOT Google Play — Play version is outdated)
# https://f-droid.org/packages/com.termux/
# In Termux:
pkg update && pkg upgrade
pkg install python3 git curl wget nmap tcpdump openssl \
tshark netcat-openbsd dnsutils
# Install Python security libs
pip install scapy requests frida-tools impacket
# Enable Termux storage access
termux-setup-storage
4.2 Frida (Dynamic Instrumentation)
Rootless Mode (Telecom-Joined Device — this setup)
# On workstation:
pip install frida-tools
# Option A: Frida via Termux (rootless — attaches to user processes)
# In Termux:
pkg install python
pip install frida-tools
# Run frida directly in Termux — can attach to own Termux processes
# Cannot attach to system/carrier processes without root
# Option B: Frida Gadget (repackage target APK)
# 1. Pull APK from device:
adb shell pm path com.carrier.app
adb pull /data/app/.../base.apk carrier.apk
# 2. Inject frida-gadget with apk-mitm or objection patcher:
pip install objection
objection patchapk --source carrier.apk
# 3. Install patched APK — Frida connects automatically on launch
# Works without root. Best for targeting specific carrier app.
# Verify (rootless attach):
frida-ps -U # lists user-accessible processes
frida -U -l bypass-ssl-pinning.js -f com.carrier.app --no-pause
Rooted Mode (Clean Device Only)
# Download frida-server for arm64:
# https://github.com/frida/frida/releases — frida-server-<version>-android-arm64.xz
# Persistent laptop-side paths used in this workflow:
# ~/Documents/mobility/frida/frida-server
# ~/Documents/mobility/frida/venv/bin/frida-ps
adb push frida-server /data/local/tmp/
adb shell su -c 'chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &'
~/Documents/mobility/frida/venv/bin/frida-ps -U # all processes visible
# Full access: carrier apps, system processes, modem RIL
4.3 SSL Interception — Burp Suite / HTTP Toolkit
Rootless — User Certificate (Telecom-Joined Device — this setup)
# ── Option A: HTTP Toolkit (easiest, no root) ─────────────────────────
# https://httptoolkit.com/android/
# Install HTTP Toolkit app → one-click HTTPS interception
# Auto-injects CA for its own VPN session — works on non-pinned apps
# Best for: REST APIs, non-hardened carrier web views
# ── Option B: Burp as user cert ───────────────────────────────────────
# Export Burp CA cert (.der): Proxy → Options → CA Certificate
openssl x509 -inform DER -in cacert.der -out burp-ca.pem
# Install via Settings → Security → Encryption & Credentials → Install cert
# Installs as USER cert — trusted by apps that respect user cert store
# NOT trusted by apps with network_security_config pinning
# Which apps trust user certs?
# Pull app's network security config:
adb shell run-as com.carrier.app cat /data/data/com.carrier.app/... # varies per app
# Or: jadx decompile and search for network_security_config.xml
User certs do NOT intercept apps that pin certificates or set cleartextTrafficPermitted=false with a custom network security config. For full MITM against hardened carrier apps, you need root (system cert store) or Frida gadget to bypass pinning.
Tested Working Setup — Pixel 9 (Android 16) + Frida + Burp
This setup has been validated on Pixel 9 (Android 16, Exynos Modem) and is ready for production MBX-02/MBX-08 testing.
Device Profile:
- Device: Google Pixel 9 (tokay), Android 16
- Modem: Samsung Exynos 5400
- Root: Magisk (uid=0 confirmed)
- Burp Suite: Community Edition listening on *:8080
Setup Summary:
# 1. Install Frida on laptop
pip install frida-tools
# 2. Download frida-server for arm64 and push to device
wget https://github.com/frida/frida/releases/download/17.9.8/frida-server-17.9.8-android-arm64.xz
xz -d frida-server-17.9.8-android-arm64.xz
adb push frida-server-17.9.8-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
# 3. Export Burp CA certificate (.der format) to laptop
# In Burp: Proxy → Options → CA Certificate → Export → DER format
# 4. Convert and install to device
openssl x509 -inform DER -in cacert.der -out cacert.pem
cert_hash=$(openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1)
cp cacert.pem ${cert_hash}.0
adb push ${cert_hash}.0 /sdcard/
# 5. Install via Magisk module (Android 14+)
# Download: https://github.com/NVISOsecurity/MagiskTrustUserCerts
# Or manually:
adb shell su -c "cp /sdcard/${cert_hash}.0 /system/etc/security/cacerts/"
adb shell su -c "chmod 644 /system/etc/security/cacerts/${cert_hash}.0"
# For APEX cert store (Android 11+):
adb shell su -c "mkdir -p /data/local/tmp/cacerts-apex && cp /apex/com.android.conscrypt/cacerts/* /data/local/tmp/cacerts-apex/ && cp /sdcard/${cert_hash}.0 /data/local/tmp/cacerts-apex/ && chmod 644 /data/local/tmp/cacerts-apex/*"
Launching Interception:
# Terminal 1: Start frida-server on device
adb shell su -c "/data/local/tmp/frida-server &"
sleep 2
# Terminal 2: Set up ADB reverse tunnel
adb reverse tcp:8080 tcp:8080
# Terminal 3: Force-stop target app and launch with Frida
adb shell am force-stop com.att.personalcloud # or your target app
frida -U -f com.att.personalcloud \
-l ~/ssl_bypass.js
# Or use the automated intercept.sh script (see MBX-02/MBX-08 toolkit below)
~/intercept.sh com.att.personalcloud
Verify Interception:
# 1. Check frida-server is running
adb shell ps aux | grep frida-server
# 2. List processes visible to Frida
frida-ps -U
# 3. In Burp, configure proxy:
# Proxy → Settings → Proxy listeners
# Add: 127.0.0.1:8080
# 4. Launch target app, confirm traffic in Burp Console
Known Issues & Workarounds:
| Issue | Symptom | Workaround |
|---|---|---|
| adb reverse not routing Chrome traffic | Chrome launches but traffic doesn't appear in Burp | Use HTTP Toolkit instead (confirmed working); or try adb shell settings put global http_proxy 127.0.0.1:8080 + force-stop Chrome |
| Phone can't reach laptop via direct IP | Connection refused on 172.20.10.5:8080 | Use adb reverse instead; or place laptop on phone's hotspot subnet |
| Frida attach timeout | frida: unable to attach | Ensure frida-server is running and permissions correct; restart server |
| Google domains won't intercept | Gmail, YouTube, Google Play traffic still pinned | This is by design (built-in cert pinning); test against non-Google apps or use Frida + unpinning script (see config.js below) |
| APEX cert mount lost after reboot | Burp CA no longer trusted | Re-run Magisk module or manual mount command |
Frida Configuration Files (for advanced unpinning):
Place these in your frida working directory:
// config.js — Proxy + cert configuration
var CONFIG = {
PROXY_ENABLED: true,
PROXY_HOST: "127.0.0.1",
PROXY_PORT: 8080,
CA_CERT_PATH: "/system/etc/security/cacerts/9a5ba575.0",
CA_CERT_FALLBACK: "/apex/com.android.conscrypt/cacerts/9a5ba575.0"
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = CONFIG;
}
See Also:
intercept.sh— automated launcher for MBX-02/MBX-08 testingfrida-interception-and-unpinning— repository of unpinning scripts- MBX-02 & MBX-08 Toolkit — detailed test procedures
Rooted Path — System Certificate Store (Clean Device Only)
# Export and convert Burp CA:
openssl x509 -inform DER -in cacert.der -out cacert.pem
cert_hash=$(openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1)
cp cacert.pem ${cert_hash}.0
adb push ${cert_hash}.0 /sdcard/
# Inject into system store (root required):
adb shell su -c "mount -o remount,rw /system"
adb shell su -c "cp /sdcard/${cert_hash}.0 /system/etc/security/cacerts/"
adb shell su -c "chmod 644 /system/etc/security/cacerts/${cert_hash}.0"
adb shell su -c "mount -o remount,ro /system"
adb reboot
# Android 14+: use Magisk module "MoveCA" or "TrustMeAlready" instead
# — avoids remount (bypasses dm-verity issues)
Resume Quick Reference
To resume an existing session after device reboot:
# Start frida-server on device
adb shell su -c "/data/local/tmp/frida-server &"
# Set up reverse tunnel
adb reverse tcp:8080 tcp:8080
# Intercept any app
~/intercept.sh com.app.package
Phase 5 — Modem Diagnostic Setup (Tensor G4)
5.1 Built-in Diagnostic Access
# Engineering menu — field test mode
# Dial on Pixel 9: *#*#4636#*#*
# → Phone Information → Run Ping / Network type override
# ADB modem info dump
adb shell dumpsys telephony.registry
adb shell dumpsys phone
adb shell dumpsys connectivity | grep -i "5G\|NR\|LTE"
# Current cell info
adb shell dumpsys telephony.registry | grep -iE "mcc|mnc|cid|signal|band"
# Force network type (for downgrade testing)
adb shell settings put global preferred_network_mode 0 # GSM only
adb shell settings put global preferred_network_mode 9 # LTE only
adb shell settings put global preferred_network_mode 20 # NR/5G preferred
5.2 Modem Logging — Tensor (Samsung Diag)
# Enable modem logging via hidden menu
# Dial: *#9900# → Sysdump → modem logging
# Or via ADB:
adb shell su -c "setprop persist.vendor.ril.log.diag 1"
adb reboot
# Pull modem logs
adb bugreport /tmp/pixel9_bugreport.zip
unzip /tmp/pixel9_bugreport.zip -d /tmp/bugreport/
# Look in: FS/data/vendor/radio/ for modem logs
# Parse with:
# • Wireshark (with NAS dissector) for protocol analysis
# • Samsung Modem Log Analyzer (limited public availability)
5.3 SCAT on Tensor (Limited Support)
SCAT (Smartphone Communication Analysis Tool from Seoul National University) has partial Tensor/Samsung modem support. Full NAS decode works better on Qualcomm devices.
# SCAT repo: https://github.com/fgsect/scat
pip3 install scat
# Try Samsung diag mode
scat -t samsung -a /dev/ttyUSB0 -D samsung -F output_dir/
# If modem exposes serial diag interface:
adb shell ls /dev/ttyUSB* /dev/smd* # look for diag port
5.4 Better NAS Capture — Laptop + Pixel 9 Hotspot
flowchart LR
PIX["📱 Pixel 9\n(Subscriber UE)\nReal SIM"] -->|"Mobile Hotspot"| LAP["💻 Laptop\nUERANSIM client\nor packet capture"]
LAP -->|"Wireshark capture\non hotspot interface"| CAP["NAS/GTP\nprotocol analysis"]
PIX -->|"ADB bridge"| LAP
style PIX fill:#2E75B6,color:#fff
style CAP fill:#1F3864,color:#fff# On laptop — capture Pixel 9 hotspot traffic
# Find hotspot interface
ip link show | grep -i usb # USB tethering interface
# Wireshark with NAS dissector
tshark -i <hotspot_if> -f "not port 22" -w pixel9_capture.pcapng
# For NAS decode — filter in Wireshark:
# nas-5gs (5G NAS messages)
# nas-eps (4G/LTE NAS messages)
# gtpv2 (GTP-C control plane)
Phase 6 — Testing Capabilities Matrix
graph TD
subgraph "✅ Pixel 9 Can Do Well"
G1["App-layer MITM\nBurp + cert pinning bypass"]
G2["Subscriber identity\ntesting (IMSI/IMEI)\nvia AT commands"]
G3["Network type forcing\n5G SA / NSA / LTE / 3G"]
G4["Cell info harvesting\nMCC/MNC/CID/Band/RSRP"]
G5["VoLTE/IMS testing\nSIP stack probing"]
G6["API testing\nNEF/BSS via apps"]
G7["Carrier app reversing\nFrida hooks"]
G8["eSIM RSP probing\nSM-DP+ requests"]
end
subgraph "⚠️ Pixel 9 — Limited / Workaround Needed"
W1["Full NAS decode\nUse Qualcomm device\nor UERANSIM on laptop"]
W2["Deep modem logging\nSCAT partial only"]
W3["Rogue gNB simulation\nNeed srsRAN on laptop\n+ RF hardware"]
end
subgraph "❌ Pixel 9 Cannot Do"
B1["QXDM / QPST logging\nQualcomm-only"]
B2["Run srsRAN gNB\nneeds RF hardware"]
end
style G1 fill:#2E75B6,color:#fff
style G2 fill:#2E75B6,color:#fff
style G3 fill:#2E75B6,color:#fff
style W1 fill:#E36209,color:#fff
style B1 fill:#C00000,color:#fffAT Command Access — Modem Control
# Find modem AT port
adb shell su -c "ls /dev/ttyACM* /dev/ttyUSB* /dev/smd*"
# Connect to modem AT interface (via Termux with root)
# In Termux:
su
cat /dev/ttyACM0 &
echo "AT" > /dev/ttyACM0 # basic test
echo "AT+CIMI" > /dev/ttyACM0 # read IMSI
echo "AT+CGSN" > /dev/ttyACM0 # read IMEI
echo "AT+COPS?" > /dev/ttyACM0 # current operator
echo "AT+CEREG?" > /dev/ttyACM0 # LTE/NR registration status
# Force RAT (Radio Access Technology)
echo "AT+CNMP=38" > /dev/ttyACM0 # LTE only
echo "AT+CNMP=109" > /dev/ttyACM0 # 5G NR preferred
echo "AT+CNMP=2" > /dev/ttyACM0 # automatic
# Supplementary services (for testing SS registration)
echo "AT+CCFC=0,2" > /dev/ttyACM0 # query call forwarding
Key Apps for Mobile Security Research
| App | Source | Purpose |
|---|---|---|
| CellMapper | Play Store / cellmapper.net | Live tower map, PCI/eNB/gNB correlation, crowdsourced site lookup |
| NetMonster | Play Store | Detailed cell info: band, EARFCN, ARFCN, NR-ARFCN, CID |
| Network Cell Info | Play Store | Signal maps, neighboring cells |
| Network Survey | F-Droid / GitHub | Detailed LTE/NR logging, exports CSV/GeoPackage, good for field collection |
| Tower Collector | F-Droid / GitHub | Collect and export GSM/UMTS/LTE/NR cell observations for OpenCellID/BeaconDB |
| IMSI Tool | Termux/ADB | Read IMSI/ICCID from SIM |
| Packet Capture | Play Store | No-root traffic capture (VPN-based) |
| HTTP Toolkit | httptoolkit.com | HTTPS intercept, cert pinning bypass |
| jadx | GitHub | APK decompile (run on laptop, APKs from device) |
| Drozer | GitHub | Android app attack framework |
| MobSF | GitHub | Mobile Security Framework (static+dynamic) |
| Termux:API | F-Droid | Bridge Termux to Android APIs |
| RootBeer Sample | GitHub | Test root detection bypass |
For tower / 4G / 5G monitoring on this Pixel, the most useful app mix is:
- CellMapper for tower/site mapping and crowdsourced cell correlation
- NetMonster for quick on-device band, EARFCN, NR-ARFCN, PCI, and serving/neighbor cell inspection
- Network Survey for richer exportable logging
- Tower Collector for long-running collection and export to OpenCellID/BeaconDB
Downloaded APKs are stored on the laptop under ~/Documents/mobility/apks/:
network-survey_111.apktower-collector_2170120.apk
Operational Setup for an Engagement
flowchart TD
subgraph "Research Station"
LAP["💻 Laptop\nWireshark · UERANSIM\nBurp Suite\nfrida-tools · SCAT"]
end
subgraph "Device Stack"
PIX["📱 Pixel 9 (Rooted)\nPrimary UE\nReal carrier SIM"]
QC["📱 Qualcomm Device\n(Pixel 6a / Samsung)\nDeep NAS logging\nSCAT/QXDM"]
ESIM["💳 Test SIMs\nMVNO SIMs for\nisolated testing"]
end
subgraph "Connectivity"
USB["USB-C → Laptop\nADB + tethering"]
HOT["Mobile Hotspot\n→ Laptop NIC\nfor traffic capture"]
VPN["WireGuard VPN\nto lab C2\nfor result exfil"]
end
PIX --> USB
PIX --> HOT
QC --> USB
LAP --> VPN
style PIX fill:#2E75B6,color:#fff
style QC fill:#1F3864,color:#fffRecommended Companion Hardware
| Hardware | Purpose | Cost |
|---|---|---|
| Google Pixel 6a | Tensor G1 — better SCAT support than G4; cheap secondary device | ~$200 used |
| Samsung Galaxy A series (Exynos) | Exynos modem SCAT, good for NAS research | ~$150-300 |
| USRP B205mini / HackRF One | SDR for passive monitoring, rogue cell simulation (with srsRAN on laptop) | $300-700 |
| Faraday bag / box | Isolate UE during testing — prevent accidental live network interference | $30-80 |
| MVNO test SIMs | Multiple ISPs for roaming test scenarios | $10-20/mo each |
| USB-C hub with Ethernet | ADB + tethering + Ethernet to lab simultaneously | $40 |
Security Hardening for the Research Device
# Prevent telemetry leakage during ops
adb shell settings put global auto_time 0
adb shell settings put global send_usage_stats 0
adb shell settings put secure send_usage_stats 0
# Disable Google backup (keeps data off cloud)
adb shell bmgr enable false
# Airplane mode + Wifi only when doing passive recon
# SIM in when doing active UE testing only
# Use separate Google account (burner) for Play Store apps
# Use Shelter app (work profile) to sandbox carrier apps
Quick Command Reference
# ── Device Info ────────────────────────────────────────────
adb shell getprop ro.product.model # device model
adb shell getprop gsm.version.baseband # modem firmware
adb shell getprop gsm.operator.numeric # MCC+MNC
# ── Cell Info ──────────────────────────────────────────────
adb shell dumpsys telephony.registry | grep -E "CellInfo|Signal|Band"
adb shell service call phone 39 # get neighboring cells
# ── Network State ──────────────────────────────────────────
adb shell dumpsys connectivity | grep -i "5G\|NR\|LTE\|connected"
adb shell cat /proc/net/dev # interface stats
# ── SIM Info ───────────────────────────────────────────────
adb shell service call iphonesubinfo 1 # device IMEI
adb shell service call iphonesubinfo 7 # IMSI (may need root)
adb shell service call iphonesubinfo 12 # ICCID
# ── Frida Quick Hooks ──────────────────────────────────────
frida-ps -U | grep -i "carrier\|tel\|sim" # find carrier processes
frida -U -l bypass-ssl-pinning.js -f com.carrier.app --no-pause
# ── Traffic Capture ────────────────────────────────────────
adb shell su -c "tcpdump -i any -w /sdcard/capture.pcap"
adb pull /sdcard/capture.pcap ./
Cross-References
- Theory_Threat_Model — Full threat model this device supports
- Research_NAS_Fuzzing — Penn State NAS fuzzing (Tensor partial support)
- java_blackbox_pentest — OSS/BSS API testing applies here via Burp on Pixel 9
Follow-Up Tasks
Device Strategy
Single Device — Telecom-Joined Pixel 9 (Current Setup)
graph TD
subgraph "✅ Strengths"
S1["Authentic carrier enrollment\n→ real MDM/provisioning context"]
S2["Real SIM binding\n→ genuine subscriber identity tests"]
S3["Clean network fingerprint\n→ blends in during engagements"]
S4["Cell info, NAS state, AT cmds\n→ ADB access without root"]
end
subgraph "⚠️ Constraints"
C1["No root\n→ no system cert store, limited Frida"]
C2["No bootloader unlock\n→ no Magisk, no GrapheneOS"]
C3["App MITM partial\n→ user cert only, pinning not bypassed"]
end
subgraph "🛠️ Best Tools for This Setup"
T1["NetHunter Rootless\n→ Kali chroot without any OS change"]
T2["HTTP Toolkit\n→ no-root HTTPS interception"]
T3["Frida Gadget\n→ repackage target APK for hooking"]
T4["Termux + nmap/tshark/scapy\n→ network tooling"]
T5["NetMonster / Cell Info\n→ cell data harvesting"]
end
style S1 fill:#2E75B6,color:#fff
style C1 fill:#E36209,color:#fff
style T1 fill:#1F3864,color:#fffBest used for:
- Carrier app analysis (traffic, identity, provisioning flows)
- Subscriber identity testing (IMSI/ICCID/IMEI via ADB)
- Cell info harvesting and network state manipulation
- App-layer testing against non-pinned targets
- Passive modem diagnostic logging
- Any test where an authentic carrier-enrolled device is the point
Workarounds for root-required capabilities:
| Need | Rootless Workaround |
|---|---|
| MITM against pinned apps | Frida gadget (repackage APK) |
| System-level packet capture | ADB + tcpdump via adb shell in debug mode |
| Kali toolchain | NetHunter Rootless chroot |
| Carrier app hooking | Objection patchapk + Frida gadget |
| Deep modem logging | ADB bugreport + *#9900# sysdump |
Two-Device — Ideal Research Setup
graph LR
subgraph "Device 1 — Telecom-Joined Pixel 9"
D1A["📱 Stock Android\nCarrier MDM enrolled\nReal SIM / eSIM"]
D1B["→ Carrier research\n→ Subscriber identity\n→ Authentic UE context"]
end
subgraph "Device 2 — Clean Unlocked Pixel 9 or 6a"
D2A["📱 Magisk Rooted\nUnlocked, Google Store\nMVNO test SIM"]
D2B["→ Full Frida server\n→ Burp system cert\n→ Deep modem AT access\n→ LSPosed hooks"]
end
subgraph "Laptop"
LAP["💻 Wireshark · UERANSIM\nBurp Suite · frida-tools\nSCAT · jadx · MobSF"]
end
D1A -->|"ADB + hotspot"| LAP
D2A -->|"ADB + tethering"| LAP
style D1A fill:#2E75B6,color:#fff
style D2A fill:#1F3864,color:#fff
style LAP fill:#E36209,color:#fff| Role | Device 1 (Telecom-Joined Pixel 9) | Device 2 (Clean Unlocked Pixel 9/6a) |
|---|---|---|
| OS | Stock Android, no unlock | Stock + Magisk root (or GrapheneOS) |
| SIM | Real carrier SIM | MVNO test SIM or secondary carrier |
| Root | ❌ None | ✅ Full via Magisk |
| Burp CA | User cert only | System store (all apps) |
| Frida | Gadget / rootless | Full server, all processes |
| Modem AT | Partial via ADB | Full /dev/ttyACM0 access |
| Best for | Authentic carrier context | Deep tool testing, app reversing |
| OPSEC profile | Clean — blend in | Research/lab only |
| Cost to replace | High (carrier bond) | Low (~$200 used Pixel 6a) |
Recommended split:
- Run carrier app investigation, subscriber identity testing, and any test needing MDM context → Device 1
- Run Burp full MITM, Frida system hooks, deep modem analysis, destructive tests → Device 2
- Never cross-contaminate: keep Device 1 clean, use Device 2 for anything requiring bootloader unlock
Sources: Google Pixel 9 Documentation · Android Open Source Project · Magisk GitHub · SCAT (fgsect/scat) · GrapheneOS Project · Kali NetHunter Rootless Docs · 3GPP TS 24.501