
Una PoC de la vulnerabilidad CVE-2024-56426.
Herramientas unificadas para CVE-2024-56426 dirigidas a las familias Exynos 990 Galaxy S20, S20 FE y Note20. El exploit acepta los diez nombres de modelo y los asigna a seis familias de bootloader de stock verificadas.
[!CAUTION] El paquete de claves rastreado y las imágenes generadas son capaces de fusionarse. La fusión es irreversible. Un teléfono fusionado a una clave solo puede arrancar imágenes compatibles con esa clave. Un modelo incorrecto, una revisión de reversión, un conjunto de parches o un paquete de claves erróneo pueden dejar el dispositivo en un bucle de arranque fusionado. Usa claves de desarrollo y la carga útil UFS mientras iteras. Añade
--no-fusea cada comando de preparación/firma a menos que la fusión con clave personalizada esté explícitamente prevista.
El modelo seleccionado controla tanto el ID de modelo BL1 como el TSV de parche LK del modelo exacto. Runtime artifact controla qué
firmware de stock e imágenes divididas cifradas usa la verificación previa. Las cuatro banderas no 5G que usan artefactos de runtime 5G emparejados
también parchean la verificación del ID de modelo de LK y la ruta de programación del ID de modelo.
| Bandera de modelo | Artefacto de runtime | Firmware de runtime | ID de modelo | EVT | Reversión | Probado |
|---|---|---|---|---|---|---|
G780F | G780F | G780FXXSOFYJ1 | 0x154 | 11 | 24 | ❌ |
G980F | G981B | G981BXXSNHYB1 | 0x143 | 11 | 23 | ✅ |
G981B | G981B | G981BXXSNHYB1 | 0x13D | 11 | 23 | ❌ |
G985F | G986B | G986BXXSNHYB1 | 0x142 | 11 | 23 | ✅ |
G986B | G986B | G986BXXSNHYB1 | 0x13C | 11 | 23 | ✅ |
G988B | G988B | G988BXXSNHYB1 | 0x13E | 11 | 23 | ❌ |
N980F | N981B | N981BXXSIHYH3 | 0x153 | 11 |
Las diez banderas de modelo compatibles de Galaxy S20, S20 FE y Note20 tienen un perfil de arranque KVM
opt-in solo por CLI. Compila una rama
del kernel Exynos 990
cuyo nombre contenga kvm, y añade --kvm al comando del modelo exacto, por ejemplo:```bash
python3 exploit/exploit.py --build-sboot --model G985F --no-fuse --kvm
Este perfil elimina la ruta LK H-Arx/UH, pide a EL3 que entre al kernel en EL2 y aplica la tabla de parches del monitor EL3 descifrada/recifrada correspondiente. Sigue sin estar disponible para los modos de flasheo del bootloader de serie/modificado. El centro de control web no incluye intencionadamente control de KVM. Con el kernel correspondiente y [WindowsInQemu](https://github.com/Creeeeger/WindowsInQemu), Windows puede ejecutarse en QEMU en el teléfono a máxima velocidad mediante KVM.
## Inicio rápido
No trates cada modo como una secuencia de instalación numerada. Elige un objetivo:
| Objetivo | Ruta |
|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
| Instalar una ROM personalizada firmada | Modelo/configuración exactos → EUB → cadena temporal `--signed --no-fuse` → flashear la salida firmada completa de la ROM → primer arranque UFS |
| Probar el exploit | Opcional `--prepare --no-fuse` → EUB → `--signed --no-fuse` → detener |
| Desarrollar la cadena de arranque (solo CLI) | Prueba temporal sin fuse → compilar → flashear SBoot/TZSW/LDFW generados → UFS |
| Volcado / recuperación | Usa su flujo de trabajo independiente y las comprobaciones de estado de fusibles |
`--prepare` es una prueba en seco recomendada, no un requisito previo obligatorio: `--signed`
repite la verificación previa. El comando Heimdall de tres partes generado es una herramienta de desarrollo de la cadena de arranque; no es un flasheo de ROM personalizada.
Lee [USER_GUIDE.md](https://github.com/creeeeger/cve-2024-56426/blob/exynos990/USER_GUIDE.md) y elige su flujo de trabajo correspondiente antes de tocar un dispositivo. Incluye la entrega de la ROM completa además de las reglas de recuperación para estados sin fusible, con fusible e inciertos.
## Interfaz local opcional
La interfaz del navegador usa solo la biblioteca estándar de Python y llama a la CLI existente
`exploit/exploit.py`. El desarrollo de la cadena de arranque y su comando Heimdall de tres partes generado siguen siendo herramientas exclusivas de terminal.
Iníciala desde la raíz del repositorio:```bash
python3 exynos990_control_center.py
El launcher se vincula a 127.0.0.1, genera un nuevo token de acceso, imprime la URL local completa y la abre en el navegador predeterminado. Usa --no-browser cuando no se deba abrir un navegador automáticamente:```bash
python3 exynos990_control_center.py --no-browser
La interfaz proporciona:
- comprobaciones en rojo/verde de dependencias y activos del repositorio;
- una única elección global de modelo objetivo y exactamente dos decisiones de fusible: Permanecer sin fundir o Fundir;
- un selector de flujo de trabajo que muestra y numera únicamente los pasos del flujo seleccionado;
- flujos de trabajo de instalación de ROM, prueba de exploit, volcado de BootROM y restauración de stock;
- una acción de cargador manipulado específica del modelo que valida la UH y la flashea en la ranura BOOTLOADER con Heimdall para entrar en EUB;
- una advertencia permanente de fusible y la huella SHA-256 configurada de la clave/eFuse;
- una tarjeta de restauración de la cadena de arranque de stock solo sin fundir que no está disponible después de elegir Fundir;
- salida de proceso en vivo, cancelación y marcadores de verificación por etapa.
También muestra un aviso de KVM de Exynos 990 solo para CLI, pero deliberadamente no expone una opción KVM ni reenvía `--kvm` a ninguna acción web.
El acceso USB sigue los permisos del proceso que inició el centro de control. Configure los permisos de udev/controlador suministrados antes de iniciarlo. La interfaz no solicita, retiene ni reenvía credenciales de privilegios. Mantenga privada la URL del token impresa y detenga el servidor inmediatamente después de usarlo.
Los usuarios de terminal pueden ignorar `exynos990_control_center.py`; todos los comandos CLI documentados a continuación permanecen sin cambios y totalmente compatibles.
## Requisitos
Se requiere Python 3.10 o superior.
Windows 10/11 (PowerShell nativo):```powershell
.\windows\setup.ps1
. .\windows\activate.ps1
python .\exploit\exploit.py --prepare --model G985F --no-fuse
La configuración instala un toolchain nativo AArch64 fijado, LZ4, Heimdall y un entorno virtual del repositorio, y luego compila todos los payloads. El controlador WinUSB de BootROM es una opción explícita de Administrador porque su certificado autofirmado upstream cambia los almacenes de confianza de la máquina. Consulta WINDOWS.md para el proceso completo de configuración, instalación del controlador, distinción del modo Download, verificación y resolución de problemas.
Después de la activación de Windows, usa python dondequiera que los ejemplos multiplataforma restantes muestren python3.
Linux:```bash sudo apt-get update sudo apt-get install -y gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu lz4
macOS:```bash
brew tap messense/macos-cross-toolchains
brew install aarch64-unknown-linux-gnu lz4
La preparación, la firma y los modos de payload ejecutan el mismo preflight consciente del modelo:
exploit/extra/images/<model>/ con una copia limpia de las imágenes divididas cifradas intactas.--no-fuse, generar primero una copia efectiva del TSV con las cinco filas de fusión deshabilitadas. Con --kvm, habilitar también las filas de LK marcadas como kvm, descifrar y parchear el TSV del monitor EL3 correspondiente, y volver a cifrar su región protegida.mem.bin, loader.bin y Exynos990_boot_custom_key.bin.El proceso se detiene ante la primera discrepancia de firmware, parche, metadatos o firma. Nunca parchea los directorios fuente inmutables en su lugar.
Todos los comandos requieren --model.
--no-fuse es un modificador, no un modo independiente. Deshabilita cinco filas OTP identificadas de clave personalizada al reconstruir el LK de trabajo. Úsalo para cada comando que prepare, envíe o construya una cadena de desarrollo sin fusión. No deshace una fusión existente.
La CLI acepta el modificador con los modos UFS y dump porque esos comandos también ejecutan preflight, pero sus operaciones USB no transmiten el LK reconstruido. El LK ya flasheado en el teléfono determina el comportamiento de fusión UFS. En consecuencia, la interfaz de usuario no ofrece deliberadamente ningún control de no-fusión para el modo UFS o de volcado del BootROM. Ambos modos de flasheo del bootloader rechazan --no-fuse porque no realizan parcheo ni firma de LK.
--kvm también es un modificador. Se acepta con cada flujo de trabajo del modelo exacto que ejecuta preflight. Las filas KVM en los TSV se ignoran a menos que este indicador esté presente, y la interfaz de usuario del navegador nunca lo proporciona.
Ejemplo:```bash python3 exploit/exploit.py --signed --model N986B --no-fuse
Genera el bootloader firmado correspondiente sin abrir USB:```bash
python3 exploit/exploit.py --build-sboot --model N986B --no-fuse
El comando reconstruye el directorio de imágenes del modelo a partir de entradas limpias de stock, aplica el parche LK, firma y verifica cada
componente, fusiona sboot.bin, comprueba los componentes integrados y la cola, e imprime su tamaño, SHA-256 y un comando Heimdall
que envía sboot.bin, tzsw.img firmado y ldfw.img firmado.
Solo en un dispositivo que se sepa que no está fusionado, restaura la cadena de arranque de stock exacta desde el tar BL original del modelo seleccionado:```bash python3 exploit/exploit.py --flash-stock --model N986B --wait
El comando extrae únicamente `sboot.bin.lz4`, `tzsw.img.lz4` y
`ldfw.img.lz4`, los descomprime en un directorio temporal, verifica que los tres archivos de salida estén presentes y no estén vacíos, e
invoca una operación de flasheo de Heimdall. Los archivos temporales se eliminan después. También se admiten
`--no-reboot` y `--verbose`. El teléfono ya debe estar en un modo de descarga compatible con Heimdall, y el modelo seleccionado debe coincidir exactamente
con el dispositivo físico.
Esto no restaura Android, AP, módem, CSC, userdata ni una ROM stock completa. Nunca lo ejecutes en un
dispositivo con fusión de clave personalizada. Un teléfono así requiere software basado en stock firmado nuevamente con la clave fusionada exacta; la raíz de confianza personalizada permanece
permanente. Si se desconoce el estado de la fusión, detente.
## Nota sobre recuperación FRP / PERSISTENT
> [!CAUTION]
> Este procedimiento es solo para un dispositivo que poseas personalmente y estés
> autorizado a reparar. Usarlo en el dispositivo de otra persona está estrictamente
> prohibido. Una ruta de partición incorrecta puede causar pérdida permanente de datos o dejar
> el dispositivo sin poder arrancar. Haz una copia de seguridad de la partición de destino y verifica su ruta
> de dispositivo de bloque resuelta y su tamaño antes de escribir cualquier cosa.
Este repositorio no elimina automáticamente la Protección de Restablecimiento de Fábrica (FRP). En dispositivos que usan el
`PersistentDataBlockService` de Android, el estado de FRP se almacena en la partición comúnmente llamada `PERSISTENT`. Consulta la
[implementación de AOSP](https://android.googlesource.com/platform/frameworks/base/+/bc56632da95b/services/core/java/com/android/server/PersistentDataBlockService.java).
Después de que la cadena de explotación haya arrancado una recuperación personalizada que proporcione `adb` y
`dd`, identifica y haz una copia de seguridad de la partición. No sustituyas una ruta de dispositivo de bloque numérica adivinada:```bash
adb shell ls -l /dev/block/by-name/PERSISTENT
adb shell dd if=/dev/block/by-name/PERSISTENT of=/tmp/PERSISTENT.backup.img bs=4096
adb pull /tmp/PERSISTENT.backup.img
Solo después de que se haya extraído la copia de seguridad, ponga a cero la partición y deje que Android inicialice una nueva estructura de bloque de datos persistentes:```bash adb shell dd if=/dev/zero of=/dev/block/by-name/persistent reboot
Este método está probado y funciona, FRP se elimina y el dispositivo queda desbloqueado.
## Parches LK
La selección de parches sigue el mapeo de artefactos:```text
G780F -> lk_g780f_selected_patches.tsv
G980F -> lk_g980f_selected_patches.tsv (applied to G981B LK)
G981B -> lk_g981b_selected_patches.tsv
G985F -> lk_g985f_selected_patches.tsv (applied to G986B LK)
G986B -> lk_g986b_selected_patches.tsv
G988B -> lk_g988b_selected_patches.tsv
N980F -> lk_n980f_selected_patches.tsv (applied to N981B LK)
N981B -> lk_n981b_selected_patches.tsv
N985F -> lk_n985f_selected_patches.tsv (applied to N986B LK)
N986B -> lk_n986b_selected_patches.tsv
Valida un TSV contra el LK estándar sin modificarlo:```bash
python3 external/tools/apply_lk_patches.py
bootLoaderFiles/sbootSplitParts_original/G986B/lk.bin
external/ghidra/lk_g986b_selected_patches.tsv
--check
`external/ghidra/ApplyLkPatches.java` acepta el mismo formato TSV de seis columnas y ahora falla ante discrepancias de bytes antiguos
en lugar de aplicar un parche a ciegas. Las filas cuya primera columna es `kvm` requieren un argumento adicional `--kvm` en el script.
Las filas heredadas `check_signature` y `check_ext4_signature` con retorno cero usan el
perfil `0`: documentan las ubicaciones antiguas de bypass pero deliberadamente no se
aplican, por lo que las imágenes construidas deben cumplir con las verificaciones de firma reales de Samsung de LK.
## Firma
`external/tools/sign_sboot_images.py` requiere un modelo y deriva el ID del modelo, EVT y la revisión de rollback de
[model_data.py](https://github.com/creeeeger/cve-2024-56426/blob/exynos990/external/tools/model_data.py):```bash
python3 external/tools/sign_sboot_images.py \
--images-dir exploit/extra/images/G986B \
--keys-dir external/keys/exynos9830_crecker \
--model G986B
Las firmas Stage2 se verifican después de firmar. La herramienta no regenera los metadatos AVB de Samsung para ldfw.img o
tzsw.img; cambiar los bytes de arranque seguro dentro de esos contenedores aún requiere la política AVB separada utilizada por el flujo de arranque
de destino. Una ROM firmada completa debe usar el modelo AVB exacto y el mismo conjunto de claves, y luego flashearse con su paquete
generado completo. Consulte el
repositorio CreckerROM
y el flujo de instalación en USER_GUIDE.md.
Los paquetes manipulados incluidos conservan todos los miembros BL de stock excepto
sboot.bin.lz4. Ese miembro se elimina y el uh.bin descomprimido del paquete
se almacena como sboot.bin, coincidiendo con el diseño que activa EUB.
La interfaz puede realizar el flujo Heimdall correspondiente directamente. Selecciona el archivo manipulado del modelo físico exacto,
verifica que sboot.bin sea byte-idéntico al uh.bin.lz4 descomprimido, y flashea la carga útil UH validada a la ranura
BOOTLOADER:```bash
python3 exploit/exploit.py --flash-tampered --model G986B --wait
Esto impide intencionalmente el arranque normal y fuerza el siguiente arranque en EUB. No flashea los miembros restantes del
tar de BL.
Regenera un paquete con:```bash
python3 external/tools/build_tampered_loader.py \
bootLoaderFiles/originalBl/G986B/BL_G986BXXSNHYB1.tar \
bootLoaderFiles/tamperedLoader/G986B/BL_G986BXXSNHYB1_tampered.tar
Usa el loader manipulado del modelo físico exacto cuando su directorio esté presente. La asignación de runtime acoplada se aplica a la verificación previa y firma del exploit, no a la selección del paquete BL de stock/manipulado archivado.
Ten en cuenta que si fusionaste el dispositivo, necesitarás flashear un uh.bin firmado en tu slot BOOTLOADER, ya que el uh de stock está actualmente firmado con la clave incorrecta.
Dividir y fusionar:```bash python3 exploit/split.py sboot.bin -o /tmp/G986B-splits python3 exploit/merge.py /tmp/G986B-splits
El merger independiente requiere `tzsw.img` y `ldfw.img` en el directorio de partes e imprime el comando Heimdall correspondiente de tres partes.
Solo use ese comando cuando esas dos imágenes ya hayan sido firmadas para el modelo seleccionado;
`--build-sboot` realiza y verifica esa firma automáticamente.
Extraer registros LDFW individuales:```bash
python3 external/tools/extract_ldfw.py ldfw.img -o LDFWs
El diseño de división proporcionado reconstruye cada sboot.bin estándar de stock byte por byte. El descifrado/re-cifrado de EPBL y el monitor EL3 también hacen un viaje de ida y vuelta byte por byte para todas las familias de firmware cuando el encabezado EPBL se deja sin cambios.
Todos los teléfonos compatibles comparten el mismo BootROM Exynos 990. Los payloads utilizan puntos de entrada comunes del BootROM y direcciones IRAM en lugar de offsets LK específicos del modelo. Los binarios generados se resuelven en estos puntos de entrada:
El comportamiento específico del modelo se limita al TSV de LK, el ID de modelo de FWBL1 y la revisión de rollback de stock.
halal-beef), a través de
halal-beef/hubble: el código backend utilizado por exploit/exploit.py; el diseño
del SoC utilizado por exploit/split.py y
exploit/merge.py; y run_exploit(), que implementa la operación de dirección/sobrescritura.VDavid003/exynos-usbdl: el esqueleto del payload del cual se derivó el payload
de clave personalizada Exynos990.18 |
| ❌ |
N981B | N981B | N981BXXSIHYH3 | 0x14E | 11 | 18 | ❌ |
N985F | N986B | N986BXXSIHYH3 | 0x152 | 11 | 18 | ❌ |
N986B | N986B | N986BXXSIHYH3 | 0x14D | 11 | 18 | ❌ |
| Ruta | Propósito |
|---|
bootLoaderFiles/originalBl/<model>/ | Paquetes BL_<firmware>.tar limpios del modelo exacto para los diez modelos. |
bootLoaderFiles/sbootSplitParts_original/<model>/ | Divisiones SBoot cifradas intactas del modelo exacto, ldfw.img, tzsw.img, manifiesto y cola. |
bootLoaderFiles/exynos9830Decrypted/<model>/ | Archivos de análisis EPBL, EL3, TZSW y LDFW descifrados del modelo exacto. |
bootLoaderFiles/tamperedLoader/<model>/ | Paquetes BL que activan EUB del modelo exacto. |
bootLoaderFiles/MODEL_COMPARISON.md | Comparación de firmware exacto versus acoplado y notas de compatibilidad de parches. |
bootLoaderFiles/exynos990Bootrom/ | Volcado compartido del BootROM Exynos 990. |
bootromNotes/ | Notas compartidas sobre el flujo del BootROM y el contexto USB. |
drivers/windows/winusb/ | Paquete WinUSB de Houston fijado para BootROM/EUB 04e8:1234. |
windows/ | Configuración nativa de Windows, activación del entorno e instalador de controladores con verificación de hash. |
exploit/extra/images/<model>/ | Salida de preflight desechable específica del modelo. |
external/ghidra/ | TSV de LK y EL3 KVM del modelo exacto más el script de parcheo de Ghidra. |
external/decompiled_G985F/ | Archivos de referencia descompilados solo para G985F. |
exynos990reverseEng_G985F/ | Proyecto Ghidra solo para G985F. |
external/keys/exynos9830_crecker/ | Paquete de claves personalizadas compartido. |
exploit/exploit.py | Punto de entrada CLI estable y coordinador del flujo de trabajo. |
exploit/build_payloads.py | Constructor de payloads nativo multiplataforma usado por preflight en Windows, Linux y macOS. |
exploit/preflight.py | Preparación de la imagen de trabajo, parcheo de LK, firma y verificación de fusión. |
exploit/usb_transport.py | Enmarcado PyUSB, descubrimiento de dispositivos, sobrescritura y transporte de volcado. |
exploit/tampered_loader.py | Extracción de UH del modelo exacto, validación del loader manipulado y flasheo EUB con Heimdall. |
exploit/stock_restore.py | Extracción del archivo stock del modelo exacto y construcción de comandos de Heimdall. |
control_center/ | Acciones del backend del navegador, comprobaciones de dependencias, trabajos y API HTTP. |
external/tools/*_crypto.py | Primitivas compartidas de cifrado/firma AES y ECDSA de EPBL/EL3. |
| Modo | Propósito |
|---|
--prepare | Ejecutar preflight sin abrir USB. |
--build-sboot | Ejecutar preflight y construir un sboot.bin firmado y verificado en el directorio de imágenes del modelo. |
--signed | Enviar el payload de clave personalizada y la cadena de arranque firmada desde EUB. |
--ufs | Iniciar la ruta de arranque UFS con loader.bin. |
--dump | Ejecutar mem.bin y volcar 0x20000 bytes del BootROM. |
--flash-tampered | Validar el UH del modelo exacto y flashearlo en BOOTLOADER para forzar EUB. |
--flash-stock | Extraer y flashear el SBoot, TZSW y LDFW stock del modelo exacto desde el tar BL original. |
| Imagen | Clave de firma personalizada |
|---|
fwbl1.img | Clave privada BL1 más blobs públicos Stage2 TEE/REE |
epbl.img, el3_mon.img | Stage2 TEE |
bl2.img, lk.bin | Stage2 REE |
ldfw.img, tzsw.img | Stage2 TEE, pies de página Stage2 internos y externos |
| Payload | Salto del exploit | Entrada vinculada |
|---|
mem.bin | 0x02022010 | 0x02022010 |
loader.bin | 0x02022010 | 0x02022010 |
Exynos990_boot_custom_key.bin | 0x02022000 | etapa 1 independiente de posición |
| Parte | Inicio | Fin |
|---|
fwbl1.img | 0x000000 | 0x003000 |
epbl.img | 0x003000 | 0x016000 |
bl2.img | 0x016000 | 0x082000 |
lk.bin | 0x0DB000 | 0x35B000 |
el3_mon.img | 0x35B000 | 0x39B000 |
| Etapa | Dirección de carga |
|---|
| BL1 | 0x02022000 |
| EPBL | 0x02026000 |
| BL2 | 0x15600000 |
| LK | 0xE8000000 |
| Monitor EL3 | 0xBFE80000 |