Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2024-20154 — Informe técnico sobre CVE-2024-20154 | Kitploit
Herramientas/GitHubGitHub/sneakid/cve-2024-20154
Seguridad de Sistemas EmbebidosSeguridad IoTAnálisis de VulnerabilidadesExplotaciónIngeniería InversaSeguridad MóvilPapers e InvestigaciónAprendizaje y EducaciónAnálisis de FirmwareExplotación de Binarios
GitHubsneakid/cve-2024-20154
21hace 2 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2024-20154

Informe técnico sobre CVE-2024-20154

Ver Repositorio

CVE-2024-20154: Desbordamiento de pila NB-IoT SIB1-NB en la banda base MediaTek MT6769

Clasificación: CWE-121 — Desbordamiento de búfer basado en pila
Gravedad: Crítica (boletín de MediaTek) · 8.8 Alta, Vector de ataque: Adyacente (CISA-ADP)
Tipo: Ejecución remota de código — sin interacción del usuario, sin asociación previa
Divulgación: Boletín de seguridad de MediaTek, 6 de enero de 2025 https://corp.mediatek.com/product-security-bulletin/January-2025 Objetivo analizado: Samsung Galaxy A14 SM-A145R — familia MT6769 (Helio G80), dentro de la lista de conjuntos de chips afectados de MediaTek - El firmware fue emulado bajo condiciones seguras. Estado: Parcheado.


Antecedentes y motivación

Esta fue mi primera investigación publicada de banda base. Vengo de un entorno muy alejado de la infraestructura de telecomunicaciones, de las capas de mediación de interceptación legal, del análisis de stingray y de captadores IMSI, y de la seguridad de dispositivos embebidos — no había hecho antes ingeniería inversa profunda de firmware en un módem celular. Quería demostrarme a mí mismo que una metodología analítica estructurada se adapta a distintos objetivos, y que la familiaridad con una plataforma específica puede reemplazarse con un rastreo riguroso de cadenas. NB-IoT destacó porque se encuentra en una intersección genuinamente peligrosa: el protocolo está diseñado para dispositivos IoT restringidos, la superficie de ataque es previa a la asociación, y la pila del módem lo procesa sin importar lo que el usuario del teléfono esté haciendo.

Cuando se analizó el firmware parcheado y se confirmó la ausencia del patrón vulnerable, el sistema de IA utilizado para el análisis masivo del firmware antes de apuntar a funciones específicas

coincidió de forma independiente con la clase de bug, las condiciones y la familia de firmware afectada reconstruidas, con la descripción de CVE-2024-20154.

Las conclusiones técnicas son del propio analista.


1. Introducción

El teléfono en tu bolsillo contiene al menos dos computadoras separadas. Con la que interactúas ejecuta Android. La otra — la banda base — funciona de forma completamente independiente, gestiona toda la comunicación por radio y es casi totalmente invisible para el sistema operativo que tiene encima. Android puede estar totalmente parcheado. El navegador puede estar en sandbox. El usuario puede no tocar nunca un enlace malicioso. Nada de eso importa si el código vulnerable está en el firmware del módem que procesa las señales de radio antes de que intervenga el procesador de aplicaciones.

CVE-2024-20154 es exactamente ese tipo de vulnerabilidad.

Una difusión de información de sistema NB-IoT malformada hace que el firmware del módem de MediaTek acepte un contador de planificación controlado por el atacante, transporte ese contador a través de la ruta de configuración RRC a L1 sin limitarlo nunca, y finalmente lo use como límite del bucle para un bucle de escritura en la pila dentro del manejador del canal de difusión NB-IoT. Cuando el contador supera la capacidad de los arrays de destino, el bucle escribe más allá de ellos, alcanza los registros guardados en la pila y sobrescribe la dirección de retorno guardada. La función restaura entonces el valor corrupto en el registro de dirección de retorno y salta a él.

Lo que hace que la gravedad sea lo que es:

  • La ruta de código vulnerable se ejecuta durante el camping de celda — después de sincronizarse con una celda pero antes de cualquier conexión RRC, autenticación o interacción del usuario.
  • La entrada es una difusión por aire (over-the-air). El teléfono no puede autenticar la fuente.
  • El firmware de la banda base en la compilación analizada se ejecuta sin ASLR, sin canarios de pila, sin pila no ejecutable y sin integridad del flujo de control. Una sobrescritura de la dirección de retorno guardada se traduce directamente en control del contador de programa.

La vulnerabilidad se publicó en el boletín de seguridad de MediaTek del 6 de enero de 2025 con una calificación de gravedad Crítica, afectando a la familia de módems LR12A, entre otras. Samsung incorporó la corrección en su versión de mantenimiento de seguridad de febrero de 2025.

Esta publicación no difunde un exploit armamentizado y no es reproducible a partir de lo que se publica aquí. El objetivo es mostrar dónde se rompe la cadena, por qué cada capa no logró detenerla y qué se necesita para validar de forma responsable un bug de banda base cuando no puedes conectar un depurador al módem en vivo.


2. Objetivo y entorno

2.1 Dispositivo y firmware

Objetivo principal: Samsung Galaxy A14 (SM-A145R). El subsistema de radio está impulsado por un procesador de banda base de MediaTek de la familia de conjuntos de chips MT6769 (Helio G80). La familia MT6769 está explícitamente incluida en la lista de conjuntos de chips afectados de MediaTek para CVE-2024-20154.``` AP/CP firmware: A145RXXU1AWD1 Modem software: MOLY LR12A.R3.TC10.6M.A14.PR.SP.V1.P5 Build date: 2023-04-18

root@kitploit:~
El firmware de banda base no es código de Android. Es un sistema embebido independiente en el subsistema de radio
del SoC, con su propia CPU, su propio RTOS y su propio espacio de memoria, fuera del
sandbox de procesos de Android.

### 2.2 Arquitectura del módem

El análisis del binario extraído muestra que el procesador del módem ejecuta MIPS32 con
instrucciones comprimidas MIPS16e2 en modo little-endian. MIPS16e2 es una extensión de codificación de 16 bits para
reducir el tamaño del código embebido — consistente con el enfoque de MediaTek para las
bandas base de la generación Helio, confirmado por investigación independiente publicada sobre bandas base de esta familia de SoC.

El sistema operativo es Nucleus RTOS, que proporciona planificación de tareas, colas de mensajes IPC y un
asignador de memoria basado en pools. No hay separación de privilegios kernel/usuario, no hay
aplicación de unidad de protección de memoria entre tareas y no hay mecanismo de protección de pila por hardware.

Todas las direcciones en esta publicación son direcciones virtuales, tal como se cargan en Ghidra en la base `0x90000000`.

### 2.3 Mitigaciones (observadas en la compilación analizada)

| Mitigación | Estado | Efecto |
|---|---|---|
| ASLR | Ausente | Las direcciones del firmware son estáticas y predecibles a partir de la imagen |
| Canario de pila | Ausente | `SAVE`/`RESTORE` almacena registros guardados por el callee sin valor centinela |
| NX / W^X | Ausente | La memoria de pila es ejecutable |
| CFI | Ausente | Las direcciones de retorno no se validan contra ninguna política |

### 2.4 Enfoque del análisis

Tres vías paralelas:

**Análisis estático.** Paquete de firmware de Samsung → extracción de la partición CP → `md1img.img` →
Ghidra (MIPS LE 32-bit, base `0x90000000`) con símbolos de ingeniería de MediaTek recuperados de
la sección de depuración del firmware mediante el conjunto de herramientas `mtk_bp` de NCC Group.

**Validación dinámica.** Se utilizó Unicorn Engine (emulación MIPS32) para ejecutar
rutinas específicas del firmware de forma aislada en dos fases. La fase 1 intentó probar la copia sin límites
de `si_count` en el contexto del canal a través del par de instrucciones nativas. La fase 2 ejecutó
el bucle vulnerable sobre bytes reales del firmware y confirmó que las propias instrucciones del firmware
corrompen la dirección de retorno guardada. Cuando la fase 1 no pudo ejecutarse completamente de forma nativa — porque
el entorno de objetos de servicio del RTOS requerido por la ruta de despacho CPHY no se reconstruyó —
el efecto secundario se modeló directamente y se etiquetó como tal en todas las salidas.

**Validación del lado de radio.** srsRAN 4G con un loopback ZMQ — solo software, sin emisión de RF —
confirmó que la carga útil de prueba sobrevive a la codificación PHY de NB-IoT y a la entrega del bloque de transporte.

---

## 3. Superficie de ataque: NB-IoT y SIB1-NB

### 3.1 Superficie de ataque previa a la asociación

NB-IoT (Internet de las Cosas de Banda Estrecha) es 3GPP Release 13, diseñado para conectar
dispositivos IoT limitados utilizando el espectro LTE con licencia existente. Está implementado en una amplia gama de
SoC celulares modernos, incluidos los de los teléfonos inteligentes de consumo.

Mientras está en RRC_IDLE, antes de que se establezca cualquier conexión RRC, un dispositivo que busca
servicio deberá:

1. Sincronizarse con las señales de temporización de la celda (NPSS/NSSS)
2. Decodificar el Bloque de Información Maestro a través de NPBCH (ventana de transmisión de 640 ms)
3. Decodificar SIB1-NB desde NPDSCH (programación de 2560 ms)
4. Usar la información de programación en SIB1-NB para localizar bloques de información de sistema adicionales

En el paso 3, el módem procesa un mensaje de una entidad que no ha autenticado, antes de cualquier
conexión o interacción del usuario. Un transmisor rogue que satisfaga las condiciones normales de selección de celda
será procesado.```
+------------------+                   +---------------------+
|  Rogue Base Stn  |                   |  Target UE (Modem)  |
+--------+---------+                   +----------+----------+
         |                                        |
         |   NPSS/NSSS sync                      |
         |--------------------------------------->|
         |   MIB-NB (640 ms cycle)                |
         |--------------------------------------->|
         |   SIB1-NB (malformed, si_count > 8)    |
         |--------------------------------------->|   ← vulnerability triggered
         |   [no RRC connection established]      |

3.2 El campo de recuento de planificación

SIB1-NB está definido en 3GPP TS 36.331. Su campo schedulingInfoList transporta cuántos mensajes de información de sistema difunde la celda, limitado por la especificación a un máximo de 8 entradas (1..maxSI-Message-NB-r13 = 8). Esta es una restricción a nivel de protocolo. La restricción de seguridad de memoria — que la longitud de la lista no debe exceder la capacidad de los arrays de destino — debe ser aplicada por separado por el firmware.

No lo fue.


4. Extracción de firmware y recuperación de símbolos

El firmware se obtuvo de un paquete CP de Samsung y se extrajo utilizando el conjunto de herramientas mtk_bp de NCC Group:``` md1img.img → md1_extract.py → 000_md1rom (17.8 MB code image) → 017_md1_dbginfo (XZ-compressed CATI debug symbols)

root@kitploit:~
La sección de depuración CATI fue descomprimida y analizada con `mtk_dbg_extract.py symbols`, y luego importada en Ghidra mediante `ImportSymbolsScript.py`. El resultado fueron nombres completos de funciones internas en todo el stack del módem — capa ERRC, gestión de canales L1, subsistema IPC y la cadena de manejadores BCCH de NB-IoT — lo que permitió una reconstrucción de la cadena guiada por semántica.

Todos los nombres de funciones en esta publicación provienen de los símbolos de depuración embebidos propios de MediaTek, extraídos de la imagen de firmware.

---

## 5. Vulnerabilidad

### 5.1 El bucle vulnerable

`el1_ch_nbcch_resume_req` (`0x90213940`) gestiona el evento de reanudación del canal de difusión NB-IoT.
Su prólogo de función MIPS16e2:```asm
90213940:  save  0xE8, ra, s0-s1

La instrucción SAVE decrementa sp en 0xE8 y almacena los registros guardados por la función llamada de manera descendente:``` old_sp (= new_sp + 0xE8) new_sp + 0xE4 saved ra ← overflow target new_sp + 0xE0 saved s1 new_sp + 0xDC saved s0 new_sp + 0x98 si_sched_arr [34 halfwords = 68 bytes] new_sp + 0x78 si_type_arr [32 bytes] new_sp + 0x00 ← stack pointer after SAVE

root@kitploit:~
De la descompilación de Ghidra del binario de firmware real:```c
for (uVar6 = 0; uVar6 < (byte)param_2[0x40a]; uVar6 = uVar6 + 1) {
    si_type_arr[uVar6]  = /* SI type byte */;          // 1 byte/iter, base new_sp+0x78
    si_sched_arr[uVar6] = /* SI schedule halfword */;  // 2 bytes/iter, base new_sp+0x98
}

param_2[0x40a] es ch_ctx[+0x40A] — un byte persistente en la estructura BSS del contexto de canal. El límite del bucle se usa directamente, sin comparación previa con las capacidades de los arreglos.

5.2 La aritmética del desbordamiento

El flujo A (escrituras de halfword sh) comienza en new_sp+0x98 y avanza 2 bytes por iteración. Alcanza el RA guardado en new_sp+0xE4 en la iteración 38:``` new_sp + 0x98 + i×2 = new_sp + 0xE4 i = (0xE4 - 0x98) / 2 = 0x4C / 2 = 38

root@kitploit:~
Flujo B (escrituras del byte `sb`) comienza en `new_sp+0x78` y requeriría la iteración 108 para alcanzar la ranura RA:```
new_sp + 0x78 + i = new_sp + 0xE4
i = 0xE4 - 0x78 = 108

Con si_count = 40 (el valor de demostración, elegido para superar el umbral de desbordamiento de 38) el bucle ejecuta 40 iteraciones. El flujo B nunca llega a la ranura RA. La corrupción de RA proviene enteramente del flujo A.

Después de 40 iteraciones, la instrucción MIPS16e2 RESTORE recarga el valor corrupto desde la pila en $ra, y jrc ra transfiere el control.

5.3 La copia sin límites — Capa B

ch_ctx[+0x40A] es escrito por el1_ch_nbcch_start en 0x90213444. Dos instrucciones MIPS consecutivas sin nada entre ellas:```asm ; el1_ch_nbcch_start @ 0x90213444 lbu v0, 0x99(s0) ; read IPC_msg[+0x99] = si_count from CPHY_CFG_REQ sb v0, 0x40A(s1) ; write to ch_ctx[+0x40A] — no clamp, no mask, no compare

root@kitploit:~
### 5.4 El constructor ERRC — Capa A

El buffer `CPHY_CFG_REQ` se construye en la capa ERRC a partir del SIB1-NB decodificado. La función
`errc_chm_l1_set_bcch_si_reception` escribe `IPC_msg[+0x99]`:```c
// errc_chm_l1_set_bcch_si_reception — Layer A
// Loop bound: decoded schedulingInfoList entry count from SIB1-NB

while (bVar3 < *(byte *)(param_3 + 0x44) && (param_2 != 0)) {
    bVar3++;
    if (uVar2 != param_2) {
        *param_5 = *param_5 + 1;   // CPHY_CFG_REQ[+0x99]++ — no upper bound check
    }
}

El límite del bucle es el número de entradas decodificadas de SIB1-NB. El contador se incrementa una vez por entrada decodificada, tantas veces como entradas se hayan decodificado, sin ningún control de límite máximo.

5.5 La ruta de IPC

Una vez que el búfer CPHY_CFG_REQ se ha rellenado, ERRC lo despacha a L1 con sap_id = 0x501F como clave de enrutamiento:``` el1_ch_rcv_ilm (sap 0x501F) → el1_chmgm_errc_cfg_req_in_idle ← stores CPHY_CFG_REQ @ L1_ctx[+0x323C] → el1_chmgm_nbcch_handler → el1_ch_nbcch_main → el1_ch_nbcch_cphy_cfg_req_process ← validates cell identity, no si_count check → el1_ch_nbcch_start @ 0x90213444 ← Layer B: lbu + sb, no clamp

root@kitploit:~
### 5.6 Ausencia de limitación en tres capas

| Capa | Función | Dirección | ¿Limitación presente? |
|---|---|---|---|
| A — Constructor ERRC | `errc_chm_l1_set_bcch_si_reception` | Rango ERRC | **Ninguna** |
| B — Copia L1 | `el1_ch_nbcch_start` | `0x90213444` | **Ninguna** |
| C — Bucle L1 | `el1_ch_nbcch_resume_req` | `0x90213940` | **Ninguna** |

Cualquier comprobación única en cualquiera de las capas habría roto la cadena.

### 5.7 Causa raíz

Una invariante vulnerada:

> El número de entradas de programación de SI nunca debe superar la capacidad del array de destino.

3GPP proporciona el límite de protocolo previsto (8 entradas). El firmware debía imponer el límite de seguridad de memoria en cada capa donde el recuento se convierte en un índice o límite de bucle. En la compilación vulnerable, el recuento viajaba desde el campo de difusión SIB1-NB a través del decodificador ERRC, hasta el mensaje CPHY_CFG_REQ, cruzando un límite de IPC hacia la tarea L1, hacia el contexto de canal BSS, y hasta un bucle de escritura en pila — sin que ninguna capa lo limitara.

---

## 6. La cadena de llamadas: cómo se encontró

### 6.1 La confusión de las dos rutas

Dos rutas estructuralmente similares pero distintas pueden entregar un búfer de configuración de 0x760 bytes a `el1_ch_nbcch_main`:

| Ruta | Origen | Valor `[+0x99]` | Relevancia |
|---|---|---|---|
| Ruta A (ERRC → IPC L1) | ERRC construye CPHY_CFG_REQ a partir de SIB1-NB decodificado | `schedulingInfoList.count` desde OTA | **La ruta vulnerable** |
| Ruta B (L1 interna) | `el1_ch_scs_ind_send` construye el cuerpo del IPC interno | Valor fijo `1` | No vulnerable |

La ruta B confirmó el formato del mensaje: el byte `+0x99` es el recuento de SI consumido por `el1_ch_nbcch_start`. Como su recuento está siempre codificado de forma fija a 1, no puede desbordarse. La ruta influenciada externamente es la ruta A.

### 6.2 La búsqueda del escritor

La búsqueda de patrones en el firmware de cualquier instrucción que escriba en el desplazamiento `+0x99` produjo ruido: T1 (`sb` directa, ~100 coincidencias), T2 (base dividida, 5 coincidencias), T3 (desplazamiento calculado, 0), T4 (`sh`/`sw` superpuestas, ~465). Las funciones de gestión de canal de ERRC estaban ausentes de la lista de referencias cruzadas de `msg_send6` porque ERRC usa `errc_com_send_msg`. Una sonda de emulación confirmó que la escritura estaba en el lado de ERRC: ejecutar el harness de Unicorn desde el despachador de L1 y observar las escrituras al desplazamiento `+0x99` del búfer no capturó nada del lado de L1.```
[RUN] dispatcher=0x90214418  watching IPC_msg+0x99

NO writes to IPC_msg+0x99 caught from dispatcher.
Write happened before el1_ch_nbcch_main — confirmed ERRC-side.

6.3 Resolución mediante clave de enrutamiento IPC

Tras sap_id = 0x501F en errc_com_send_msg se identificó el enrutamiento hacia el1_chmgm_errc_cfg_req_in_idle, que almacena el puntero CPHY_CFG_REQ en L1_ctx[+0x323C] e inicia el despacho posterior.

6.4 Cadena de llamadas confirmada```

SIB1-NB schedulingInfoList.count (demonstrator: 40) │ ▼ [ERRC task] errc_chm_ch_ctrl_req_hdlr → errc_chm_call_ctrl → errc_chm_l1_main → errc_chm_l1_call_ctrl → errc_chm_l1_snd_cphy_cfg_req ← allocates 0x760-byte CPHY_CFG_REQ → errc_chm_l1_set_cphy_req_nbcch_cfg → errc_chm_l1_set_bcch_inf → errc_chm_l1_set_bcch_si_reception ← Layer A: CPHY_CFG_REQ[+0x99] = 40 → errc_com_send_msg(sap=0x501F) ← IPC to L1 │ ▼ [L1 task] el1_ch_rcv_ilm (sap 0x501F) → el1_chmgm_errc_cfg_req_in_idle ← stores CPHY_CFG_REQ @ L1_ctx[+0x323C] → el1_chmgm_nbcch_handler → el1_ch_nbcch_main → el1_ch_nbcch_cphy_cfg_req_process ← no si_count validation → el1_ch_nbcch_start @ 0x90213444 ← Layer B: lbu + sb, no clamp │ ▼ ch_ctx[0x40A] = 40 (persists in BSS) │ ▼ [state machine advances to 0x0B, event 0x2C] el1_ch_nbcch_resume_req @ 0x90213940 ← Layer C: loop bound from ch_ctx[0x40A] │ ▼ stack overflow → jrc ra → PC = attacker-controlled

root@kitploit:~
---

## 7. Validación

Este modelo específico SM-A145R no parece ejercitar
la ruta de código vulnerable de NB-IoT en la operación normal de compilación de fábrica, por lo que se utilizaron emulación híbrida
y análisis estático en lugar de reproducción directa en hardware.

**Comprobado estáticamente.** El binario del firmware contiene el par de instrucciones vulnerable. La cadena de llamadas
se reconstruye a partir de símbolos, referencias cruzadas y cuerpos de funciones descompilados.

**Ejecutado nativamente en emulación.** El bucle dentro de `el1_ch_nbcch_resume_req` se ejecutó sobre bytes reales
de firmware de MediaTek en Unicorn Engine (MIPS32). La propia instrucción `sh` del firmware en
`0x90213B02` escribió en la ranura de dirección de retorno guardada. La instrucción `RESTORE` cargó el
valor corrupto en `$ra`, y `jrc ra` transfirió el control.

**Modelado explícitamente.** La copia `lbu`/`sb` en `el1_ch_nbcch_start` no pudo ejecutarse completamente
de forma nativa porque la ruta de despacho de la tabla de callbacks del RTOS dentro de `el1_ch_nbcch_cphy_cfg_req_
process` esperaba objetos vivos del heap de Nucleus que el emulador plano no proporcionaba. El manejador de reanudación
(`el1_ch_nbcch_resume_req`) en la Fase 2 solo lee del contexto de canal residente en BSS
y no pasa por esa misma ruta de despacho, por lo que la Fase 2 se ejecutó nativamente sin
requerir el mismo andamiaje. El efecto secundario de la Fase 1 — un byte de `IPC_msg[+0x99]`
escrito en `ch_ctx[+0x40A]` — se modeló directamente y se etiquetó como `[PHASE1-MODEL]`.

**No afirmado.** Una reproducción completa de extremo a extremo over-the-air en hardware.

### 7.1 Antimanipulación

El harness impuso una regla: ningún hook podía escribir el marcador de prueba en la ranura
de dirección de retorno guardada. Se rastreó cada escritura de memoria que no fuera del firmware.```
[PROOF-W] saved_RA write: pc=0x90213b02  addr=new_sp+0xE4  value=0xbeef
[PROOF-W] saved_RA write: pc=0x90213b02  addr=new_sp+0xE6  value=0xdead
[ANTI-TAMPER] no hook wrote RA=0xDEADBEEF — firmware only
anti_tamper_fail = False

0x90213B02 es la instrucción sh dentro del cuerpo del bucle. El firmware colocó estos bytes en el desplazamiento de pila previsto. En almacenamiento little-endian, las medias palabras 0xBEEF y 0xDEAD en new_sp+0xE4 y new_sp+0xE6 se combinan en [ef be ad de] = 0xDEADBEEF.

7.2 Resultado de la emulación```

[REGS] RA = 0xdeadbeef ← firmware wrote this; decisive proof PC = 0x00000000 ← Unicorn unmapped-fetch artifact, not a hardware exception vector

[STACK] new_sp+0xE4: [ef be ad de] ← little-endian 0xDEADBEEF

[PC-EXPLAIN] PC=0 is an unmapped-fetch artifact; decisive proof is RA=0xDEADBEEF + stack bytes [ef be ad de] + [PROOF-JRC] CONFIRMED: saved RA = 0xDEADBEEF

root@kitploit:~
### 7.3 Entrega ZMQ

Para confirmar que la carga útil de prueba sobrevive a la codificación PHY de NB-IoT y a la entrega de bloques de transporte, se utilizó srsRAN 4G con un loopback ZMQ (sin emisión de RF). La carga útil era un vector deliberadamente no conforme: la restricción ASN.1 SIZE en `schedulingInfoList` se relajó para permitir 40 entradas, y la decodificación de ida y vuelta con pycrate confirmó el campo de recuento en el byte 14.```
SIB1 received
SIB2 activated
exit 0

Esto confirma la entrega en la capa de transporte. El comportamiento ASN.1 del lado del firmware queda establecido por el análisis estático de la Capa A.


8. Mecánica del flujo de control

8.1 Dos fases, una tarea, estado persistente

La tarea el1_ch tiene una sola pila. La Fase 1 y la Fase 2 son dos eventos IPC separados procesados secuencialmente por la misma tarea, con la pila desenrollándose por completo entre ambas. El contador persiste en el contexto del canal en BSS, no en la pila:``` EVENT: CPHY_CFG_REQ (Phase 1) el1_ch_nbcch_start lbu v0, 0x99(s0) sb v0, 0x40A(s1) ← ch_ctx[0x40A] = attacker value, written to BSS returns — stack fully unwound

EVENT: resume (state 0x0B, msg 0x2C) (Phase 2) el1_ch_nbcch_resume_req ← frame 0xE8, reads ch_ctx[0x40A] as loop bound loop × 40 → saved RA corrupted jrc ra → attacker-controlled PC

root@kitploit:~
`ch_ctx[0x40A]` vive en BSS y conserva el valor del atacante hasta que el módem se reinicia o una configuración de canal posterior lo sobrescribe.

### 8.2 Marco de pila```
old_sp  (= new_sp + 0xE8)
new_sp + 0xE4   saved ra
new_sp + 0xE0   saved s1
new_sp + 0xDC   saved s0
new_sp + 0x98   si_sched_arr  [34 halfwords = 68 bytes]
new_sp + 0x78   si_type_arr   [32 bytes]

Tamaño del marco confirmado por medición de emulación. Posiciones del array confirmadas por el resultado de la emulación — RA escrito en la iteración 38, coherente con si_sched_arr comenzando en new_sp+0x98.


9. Evidencia

9.1 Compuertas antes del bucle vulnerable

9.2 Funciones confirmadas que no limitan si_count


10. Análisis del parche

10.1 Versiones

CompilaciónFirmware del módemFecha de compilación
VulnerableA145RXXU1AWD1, MOLY LR12A...V1.P52023-04-18
ParcheadoA145RXXUDDZC2, MOLY

Fechas de compilación confirmadas al extraer los metadatos de md1_dbginfo de ambas imágenes. ID del parche: MOLY00720348 · ID del problema: MSV-2392.

10.2 Qué cambió

el1_ch_nbcch_start (0x90213444 en el binario vulnerable): El par de instrucciones lbu/sb está ausente. La copia directa de IPC_msg[+0x99] en ch_ctx[+0x40A] ha desaparecido.

el1_ch_nbcch_resume_req (0x90213940 en el binario vulnerable): El bucle de escritura a la pila sobre ch_ctx[0x40A] está ausente. La arquitectura en la que un byte no confiable se convierte en un límite de bucle sobre arrays de tamaño fijo en la pila ya no existe. El cuerpo de la función se reemplaza por una estructura de despacho diferente.

errc_chm_l1_set_bcch_si_reception: El bucle de contador sin límite se reemplaza por llamadas auxiliares orientadas a la validación.

10.3 Nuevas funciones de validación

Dos funciones presentes en el binario parcheado están ausentes del binario vulnerable:``` el1_ch_nbcch_param_check el1_ch_scell_param_check

root@kitploit:~
Una comprobación de límites de una sola línea aparecería como unas pocas instrucciones añadidas dentro de una
función existente en la misma dirección. Lo que muestra el binario parcheado es una revisión arquitectónica:
la ruta de programación de NBCCH fue rediseñada de modo que el patrón de `si_count` como límite de bucle ya no
existe en ninguna parte de la ruta.

### 10.4 Atribución de CVE

La vulnerabilidad descrita aquí coincide con CVE-2024-20154 según lo publicado por MediaTek el 6 de
enero de 2025. Base de confirmación:

- La familia de firmware afectada (LR12A) coincide con el boletín de MediaTek.
- La clase de vulnerabilidad — desbordamiento de pila, falta de comprobación de límites, RCE desde una estación base maliciosa,
  sin interacción del usuario — coincide con la descripción del CVE y el registro de NVD.
- El firmware parcheado elimina exactamente las estructuras de código identificadas como vulnerables.
- El ID de parche MOLY00720348 se confirmó a partir del boletín de MediaTek y del Android Security Bulletin
  (A-376809176).
- El análisis asistido por IA relacionó de forma independiente el patrón reconstruido con CVE-2024-20154
  antes de la confirmación manual.

---

## 11. Ética y divulgación responsable

### 11.1 Lo que esta publicación no contiene

Sin exploit armamentizado. Sin contenido binario de firmware. Sin bytes de payload malformados. Sin
procedimiento paso a paso para desencadenar la vulnerabilidad contra un dispositivo real. La
información necesaria para reproducir un ataque funcional — construcción completa del payload para el
decodificador de módem específico, andamiaje de objetos de heap de RTOS para la emulación completa de la Fase 1, configuración
de radio por aire — está deliberadamente ausente.

### 11.2 Por qué el loopback ZMQ y la emulación son el enfoque ético

El loopback ZMQ significa que nunca se transmitió ninguna señal por aire. Ningún dispositivo real fue objetivo.
Ninguna red de operador estuvo involucrada. La prueba se ejecuta enteramente en un entorno de software contenido
en hardware propiedad del analista. Este es el enfoque correcto para validar una vulnerabilidad de radio previa
a la asociación — transmitir una emisión malformada afectaría a cualquier dispositivo dentro del alcance.

La emulación con Unicorn demuestra que el comportamiento vulnerable está en el propio binario del firmware,
de forma reproducible e independiente de cualquier estado específico del dispositivo o entorno de radio. Esta es una
afirmación técnicamente más sólida que un único fallo de hardware, y evita desplegar cualquier cosa
por aire.

### 11.3 Propiedad intelectual de MediaTek

Todo el análisis se realizó sobre firmware obtenido legítimamente de un dispositivo de consumo y de los
paquetes de firmware publicados públicamente por Samsung. No se utilizó documentación propietaria.
Las definiciones internas de struct de MediaTek y los formatos de mensajes IPC se describen solo en la medida
necesaria para explicar el fallo de seguridad de memoria. No se publican como especificaciones.

---
Descargar herramienta
Iteraciónsh escribe enEfecto
0–33si_sched_arr[0..33]Dentro de los límites
34–35new_sp+0xDC — s0 guardados0 corrupto
36–37new_sp+0xE0 — s1 guardados1 corrupto
38new_sp+0xE4 — ra guardado [15:0]Halfword baja de RA
39new_sp+0xE6 — ra guardado [31:16]Halfword alta de RA
CompuertaCondiciónDónde se comprueba
Ruta activa de NB-IoTcfg_type == 1el1_ch_nbcch_cphy_cfg_req_process
Canal no completadodone_flag == 0ch_ctx[0x438]
Máquina de estados 0x0BNBCCH en estado de reanudaciónDespacho de el1_ch_nbcch_main
si_count distinto de ceroch_ctx[0x40A] > 0Condición del bucle
Clase de banda ≤ 2Modo NB-IoT válidoEntrada de el1_ch_nbcch_resume_req
el1_chmgm_cell_info_get distinto de ceroCelda en la tabla de servicioSe llama en el1_ch_nbcch_start
FunciónDirecciónRol¿Limita?
errc_chm_l1_set_bcch_si_receptionRango ERRCEscribe CPHY_CFG_REQ[+0x99]No
el1_ch_nbcch_cphy_cfg_req_process0x90213F80Enruta la configuración CPHY hacia L1No aplica — no lee si_count
el1_chmgm_cell_info_get0x9020E0D0Valida EARFCN/PCINo aplica
el1_ch_nbcch_start0x90213444Copia el contador a BSSNo
el1_ch_nbcch_resume_req0x90213940Usa el contador como límite del bucleNo
LR12A...V3.P8
2025-04-23