SIGINT MONITORING STATION // SITE 7-ALPHA ● REC
CAM-01 // CELL TOWER 0x1A3F
IMEI TRACKING
35674108372408
CARRIER: REGISTERED
STATUS: LOCATED
● TRACKING
CAM-02 // WIFI PROBE CAPTURE
BSSID GEOLOCATION
94:83:C4:A1:B2:C3
WIGLE DB: MATCH
LAT: 48.8566 LON: 2.3522
● LOGGING
CAM-03 // UPSTREAM AP
MAC CORRELATION
94:83:C4:XX:XX:XX
SESSIONS: 47
LOCATIONS: 12
● CORRELATING
CAM-04 // CLIENT ENUMERATION
DEVICE INVENTORY
42 DEVICES LOGGED
FLASH: /etc/oui-tertf
FORENSIC: READY
● RECORDING

SIGNAL LOST

ALL IDENTIFIERS ERASED

REC
MASS SURVEILLANCE IS NOT SECURITY // 5.3 BILLION CELLPHONE RECORDS COLLECTED DAILY // DATA RETENTION: THEY STRUCK DOWN THE LAW BUT KEPT THE INFRASTRUCTURE // STINGRAY IMSI CATCHERS IN 27 US STATES // 802 MILLION WIFI NETWORKS IN WIGLE DB // THEY CALL IT METADATA. WE CALL IT YOUR LIFE. // PRIVACY IS NOT NEGOTIABLE // MASS SURVEILLANCE IS NOT SECURITY // 5.3 BILLION CELLPHONE RECORDS COLLECTED DAILY // DATA RETENTION: THEY STRUCK DOWN THE LAW BUT KEPT THE INFRASTRUCTURE // STINGRAY IMSI CATCHERS IN 27 US STATES // 802 MILLION WIFI NETWORKS IN WIGLE DB // THEY CALL IT METADATA. WE CALL IT YOUR LIFE. // PRIVACY IS NOT NEGOTIABLE //
red-merle
cellular identity erasure // gl-e750 mudi // v2.14.0
Every cell tower logs your IMEI. Every WiFi probe leaks your history.
Every carrier stores your location under data retention laws.
They call it national security. We call it mass surveillance.
Privacy is not a privilege. It is a right they chose to violate.
001

The problem

Your Mudi broadcasts four unique identifiers every second. Each one is a thread. Pull any thread and you unravel the user: IMEI ties them to a device, BSSID pins them on a map, MAC links their sessions, client DB inventories their contacts.

002

Attack surface

IMEI

Hardware serial. Persists across SIM swaps. Retained by carriers. Links all identities to one device.

BSSID

In every beacon frame. Indexed by WiGLE, Google, Apple. Passive collection = GPS coordinates.

WAN MAC

Visible to upstream APs. Static across reboots. Correlates sessions across locations.

Client DB

Every connected device logged to flash. Seizure = complete device inventory.

Carrier GPS

LPP/SUPL/RRLP: carrier silently requests your coordinates. Modem responds without user consent.

System logs

syslog, dmesg, shell history. Device seizure reveals full IMEI change history with timestamps.

003

Countermeasures

VectorExposureAction
IMEICarrier trackingBand-aligned TAC prefixes + Luhn-valid serial (random.choices, 10^6 keyspace)
BSSIDGeolocation DBsRandomized every boot
WAN MACAP loggingRandomized every boot
Client DBDevice seizureShredded + tmpfs (RAM only)
Carrier GPSSilent locationGNSS engine off; LPP, A-GPS modes and the Qualcomm izatcloud XTRA beacon refused via Quectel-documented AT commands — validated on EM060K-GL, re-applied at boot
SUPLUser-plane locationBlocked at network level: iptables DROP on port 7275 in both modes (trade-off: kills IPsec NAT-T)
LogsForensicssyslog, dmesg, shell history wiped at boot, after IMEI change, and at shutdown
DNSSession correlationdnsmasq cache flushed after IMEI change
004

Procedure

root@mudi● live
005

Control

root@mudired-merle-ctl
$ red-merle-ctl # interactive menu (no args) $ red-merle-ctl status # modem, firmware, IMEI, IMSI, own number, # SIM, registration, signal, network, # modes, SUPL block, boot options $ red-merle-ctl lte-only on # granular LTE-only flag (downgrade-attack protection) $ red-merle-ctl gps off # GNSS engine off $ red-merle-ctl hardening on # apply the full AT suite now; off = full revert $ red-merle-ctl imei random # show | random | deterministic | set <IMEI> $ red-merle-ctl imei pool # list the verified TAC pool (brand, type, model) $ red-merle-ctl imei type hotspot # claim a portable hotspot: closest match $ red-merle-ctl imei brand apple # or samsung | huawei | google | xiaomi $ red-merle-ctl imei native # claim a GL.iNet TAC (read the caveat first) $ red-merle-ctl esim off # stop GL's eSIM daemon and its phone-home $ red-merle-ctl sms list # read <i> | send <num> <text> | del <i> $ red-merle-ctl revert # carrier defaults: all RATs, IMS, XTRA $ red-merle-ctl config # boot options

Every boot behavior is individually switchable since v2.3.0: wipe_logs randomize_mac randomize_bssid iptables_block gps_hardening — all enabled by default, matching the historical behavior. Toggle with red-merle-ctl config <name> on|off, inspect in status. Disabled steps are honestly reported as [OFF] on the boot OLED; GPS hardening runs backgrounded and waits for the modem.

006

Identity

The IMEI the modem reports is only half the claim. Its first eight digits, the TAC, name a device model, and a carrier can resolve that against what the modem announces about itself at every attach — supported bands, UE category, aggregation combinations. Two fingerprints to compare, one database join.

So a TAC pool is only worth what its entries are worth. Every prefix shipped here is verified against a public allocation database of ~255k entries: the model named in each comment is what that TAC is genuinely registered to. An unallocated prefix resolves to nothing at all, which is louder than not spoofing. An earlier release shipped pools that had never been checked and were largely wrong; they were replaced wholesale.

Pool

42 verified prefixes per modem variant, weighted toward portable LTE hotspots — same device class as the Mudi, so months without a single voice call look normal. Fixed home routers and 3G-only devices are filtered out: one cannot travel, the other cannot camp on LTE.

Filters

Claim a class, a brand or a model: imei type hotspot, imei brand apple, imei model "iphone 15". Also in the dashboard, with the trade-off written next to the control.

Native

imei native claims a GL.iNet TAC, the only claim coherent with what the modem reports. The cost is that the prefix never changes, so it links every session — a certain link against a hypothetical flag. Narrow use only.

What it cannot do

No host-side change alters the capability report. This module advertises nine LTE bands no Galaxy S21 has, B14 among them. TAC choice defeats the cheap query, not full fingerprinting.

007

Camouflage

LuCI themes

luci-theme-red-merle ships redmerle (dark red) and redmerle-hacker (green CRT), selectable under System → Language & Style.

GL admin panel

"Red Merle" and "Red Merle Hacker" entries in the palette dropdown (top-right), applied across the stock GL.iNet interface.

GL-native dashboard

Since v2.5.0 the RED MERLE sidebar entry opens /redmerle/ — a self-contained control page that follows the active panel theme: full status, hardening/LTE-only/GNSS toggles, boot options, random IMEI, AT log. Its CGI bridge validates the Admin-Token session against gl-session before touching the modem (403 otherwise). Since v2.7.0 it also runs the complete SIM swap sequence — radio off, interim IMEI, modem reset cycle, post-swap IMEI, log wipe, GPS hardening and DNS flush — where the LuCI modal only ever did the first two steps.

Branding

Combined GL.iNet + ☢ logo, versioned Red Merle header link (theme-native styling), RED MERLE sidebar entry, Red Merle row in System Info, footer copyright.

SSH banner

Branded /etc/banner on login. Every element is re-applied by the package postinst after a firmware upgrade.

008

Deployment

localbuild
$ git clone https://github.com/franckferman/red-merle.git $ cd red-merle # Quick build (no SDK needed) $ ./build.sh # Build with OpenWrt SDK (same as CI) $ ./build.sh sdk-build # Build + deploy to Mudi via SSH $ ./build.sh install
offlineno internet on mudi
# unzip the _offline_install.zip from the release page, then $ scp -O -r red-merle_offline_install root@192.168.8.1:/tmp $ ssh root@192.168.8.1 $ cd /tmp/red-merle_offline_install && ./install.sh
post firmware upgradepostinst re-applies everything
# GL upgrades remove packages but keep /etc/config. Reinstall: $ scp -O red-merle_2.14.0_all.ipk root@192.168.8.1:/tmp/ $ opkg update && opkg install coreutils-shred python3-pyserial $ opkg install /tmp/red-merle_2.14.0_all.ipk

Validated on GL-E750 V2 (Quectel EM060K-GL, GL firmware 4.3.26, modem EM060KGLAAR01A11M2G). Other 4.x firmwares should work but display a warning during installation. If a firmware upgrade reset the OpenWrt packages feed (GL 4.x is OpenWrt 22.03-based), add it back first: src/gz openwrt_packages https://downloads.openwrt.org/releases/22.03.4/packages/mips_24kc/packages

009

Field notes

QuestionAnswer
SMS in hardening mode?Works via SMS-over-SGs — the standard LTE delivery path, including 2FA and bank codes. SMS-over-IMS is disabled with IMS.
Voice calls?Impossible in hardening mode: no VoLTE with IMS off, no 2G/3G fallback with LTE-only. Irrelevant on a data-only router SIM.
LTE-only blocks SIM registration?No. LTE-only restricts radio technologies, not network attach. Provisioning SMS arrives via SGs.
No LTE coverage?In 3G/2G-only zones the modem will not connect until you revert.
Full revert?red-merle-ctl hardening off restores the persistent modem NV settings: AUTO RAT, IMS, XTRA.
010

Lineage

Fork of blue-merle
(Security Research Labs, 2022)

Upstream stopped at June 2025. Issues answered here that are still open there: #1 TAC/band alignment (open since 2022; raises the cost of the cheap query, does not defeat capability fingerprinting — see the readme), #82 carrier GPS tracking, #38 DNS flush, #35 configurable behaviours, #22 one-shot IMEI change.

Defects fixed: IMEI entropy loss (random.sample without replacement), syslog IMEI leak, 14-digit IMEI validation, bash-only shell code, and the eSIM daemon storing a stale IMEI on disk.

1,129 → 3,291 lines · 16 → 49 band-aligned TACs · 0 → 9 configurable behaviours · 1 → 2 dashboards · a full control CLI

by Franck FERMAN