
Genera archivos TIFF/DNG manipulados para provocar escrituras fuera de los límites en libimagecodec.quram.so de Samsung, incluyendo análisis binario y pasos de reproducción.
Este repositorio contiene archivos conceptuales de Prueba de Concepto (PoC) que demuestran vulnerabilidades de escritura fuera de límites (OOB) en la biblioteca de códec de imagen Quramsoft (libimagecodec.quram.so) utilizada en dispositivos Samsung Android.
| CVE | Formato | Tipo | Severidad | CVSS 4.0 | Corregido en |
|---|---|---|---|---|---|
| CVE-2026-21045 | TIFF | Escritura fuera de límites (CWE-787) | Crítica | 8.4 | SMR Jul-2026 Release 1 |
| CVE-2026-21048 | DNG | Escritura fuera de límites (CWE-787) | Alta | — | SMR Jul-2026 Release 1 |
/system/lib64/libimagecodec.quram.soLa vulnerabilidad reside en la función de análisis de etiquetas IFD (Image File Directory) WINKJ_ReadExifField (desplazamiento 0x13a0a8 en el binario de 64 bits). Esta función procesa entradas IFD individuales de TIFF/EXIF, cada una de las cuales es una estructura de 12 bytes:
Offset Size Field
------ ---- -----
0 2 Tag ID
2 2 Data Type (1=BYTE, 2=ASCII, 3=SHORT, 4=LONG, 5=RATIONAL, etc.)
4 4 Count (number of values)
8 4 Value / Offset to data
Cuando count * element_size > 4, el campo Value de 4 bytes se trata como un desplazamiento de archivo (que apunta a dónde se encuentran los datos reales). El código realiza entonces una comprobación de límites en la dirección 0x13a258:
add w8, w6, w7 ; w8 = value_offset + (count * element_size) [32-bit]
cmp w8, w5 ; compare against remaining buffer size
b.ls ok ; if w8 <= buffer_size, proceed
La vulnerabilidad es un desbordamiento de entero sin signo de 32 bits en la suma. Si un atacante manipula value_offset y count * element_size de modo que su suma dé la vuelta (wrap around) a un valor pequeño, la comprobación se supera aunque el acceso real a memoria en base + value_offset quede fuera de límites.
Ejemplo (tipo UNDEFINED, element_size = 1):
La suma de 32 bits 0x17FFF + 0xFFFF0001 = 0x10008000 se trunca a 0x8000, que es igual a buffer_size. La comprobación se supera, pero el puntero de datos real (base + 0x17FFF) se encuentra 0x7FFF bytes más allá del final del búfer asignado.
TIFFReadDirectory / WINKJ_ReadTiffInfo
└─> WINKJ_ReadTiffIFDInfo (allocates IFD buffer)
└─> for each IFD entry:
└─> WINKJ_ReadExifField (parses entry, reads value data)
└─> Switch on Data Type (jump table at 0x13a15c)
├─ Type 0 (BYTE/ASCII/UNDEFINED): handler at 0x13a15c
├─ Type 3/8 (SHORT/SSHORT): handler at 0x13a1d0
├─ Type 4/9/11 (LONG/SLONG/FLOAT): handler at 0x13a17c
└─ Type 5/10/12 (RATIONAL/SRATIONAL/DOUBLE): handler at 0x13a1ac
Each handler -> reads data at offset -> bounds check at 0x13a258
| Archivo | Descripción |
|---|---|
cve-2026-21045_tiff_oob_poc.py | Genera poc_crash.tif — TIFF malformado que provoca una escritura OOB mediante una etiqueta ASCII con count/offset manipulados |
cve-2026-21048_dng_oob_poc.py | Genera poc_crash.dng — DNG malformado que provoca una escritura OOB mediante una etiqueta UNDEFINED con count/offset manipulados |
# Generate TIFF PoC
python3 cve-2026-21045_tiff_oob_poc.py -o payload.tif
# Generate DNG PoC
python3 cve-2026-21048_dng_oob_poc.py -o payload.dng
# Transfer to device and trigger (e.g., via Gallery/MMS)
adb push payload.tif /sdcard/Download/
adb shell am start -a android.intent.action.VIEW -d file:///sdcard/Download/payload.tif -t image/tiff
En un dispositivo sin parchear (parche de seguridad < julio de 2026), abrir el archivo TIFF/DNG manipulado en Samsung Gallery (o cualquier aplicación que use el decodificador Quram) debería provocar una corrupción de memoria heap que potencialmente puede llevar a:
En un dispositivo parcheado (SMR Jul-2026+), la imagen debería ser rechazada como inválida o procesada de forma segura. Un fallo en un dispositivo totalmente parcheado puede indicar un problema separado sin parchear.
File: libimagecodec.quram.so (64-bit)
SHA256: (verify against your copy)
NDK: r23c (Android 21)
Built: 2021-12-31 (placeholder date)
Soname: libimagecodec.quram.so
Extraído de WINKJ_ReadExifField:
Todos los tipos con element_size = 1 (BYTE, ASCII, UNDEFINED) comparten el mismo manejador y son igualmente vulnerables a la evasión por desbordamiento de entero.
Estas pruebas de concepto se proporcionan únicamente con fines educativos y de investigación en seguridad. Demuestran el mecanismo de la vulnerabilidad para ayudar a usuarios y desarrolladores a comprender el riesgo. No las utilices contra sistemas que no poseas o para los que no tengas permiso explícito de prueba.
| Campo | Valor (hex) | Decimal |
|---|
count | 0xFFFF0001 | 4,294,901,761 |
element_size | 1 | 1 |
count * element_size | 0xFFFF0001 ≡ -65535 (mod 2³²) | 4,294,901,761 |
value_offset | 0x00017FFF | 98,303 |
value_offset + count*size | 0x00008000 (¡desbordamiento!) | 32,768 |
buffer_size | 0x00008000 | 32,768 |
Resultado de la comprobación: 0x8000 <= 0x8000 | ✅ PASA | — |
Acceso real a memoria: base + 0x17FFF | 0x7FFF bytes más allá del búfer | ❌ OOB |
| Función | Dirección (64-bit) | Tamaño | Propósito |
|---|
WINKJ_ReadExifField | 0x13a0a8 | 912 | Analiza una entrada IFD individual (vulnerable) |
WINKJ_ReadTiffIFDInfo | 0x139d28 | 896 | Lee todas las entradas IFD |
WINKJ_ReadTiffInfo | 0x139ad4 | 596 | Analizador de información TIFF de alto nivel |
WINKJ_GetTiffInfo | 0x1393fc | 1752 | Punto de entrada principal del análisis TIFF |
decodeTIFF | 0x1a2adc | 580 | Decodifica imágenes TIFF mediante libtiff |
getTIFFImageInfo | 0x1a2d20 | 508 | Obtiene los metadatos de la imagen TIFF |
copySubImageBuffer | 0x0b2824 | 324 | Copia la región de la subimagen |
TIFFReadDirectory | 0x1aac78 | 5896 | Lector de directorios de libtiff 4.6.0 |
_TIFFMultiply32 | 0x1a2f1c | 56 | Comprobación segura de multiplicación de 32 bits |
_TIFFMultiply64 | 0x1a2f58 | 48 | Comprobación segura de multiplicación de 64 bits |
| Tipo | Nombre | Tamaño del elemento | Dirección del manejador |
|---|
| 1 | BYTE | 1 | 0x13a15c |
| 2 | ASCII | 1 | 0x13a15c |
| 3 | SHORT | 2 | 0x13a1d0 |
| 4 | LONG | 4 | 0x13a17c |
| 5 | RATIONAL | 8 | 0x13a1ac |
| 6 | SBYTE | 1 | 0x13a15c |
| 7 | UNDEFINED | 1 | 0x13a15c |
| 8 | SSHORT | 2 | 0x13a1d0 |
| 9 | SLONG | 4 | 0x13a17c |
| 10 | SRATIONAL | 8 | 0x13a1ac |
| 11 | FLOAT | 4 | 0x13a17c |
| 12 | DOUBLE | 8 | 0x13a1ac |
| CVE | Descripción | Estado |
|---|
| CVE-2025-58477 | Escritura OOB en el análisis de etiquetas IFD en libimagecodec.quram.so (SMR Dec-2025) | ✅ Parcheado |
| CVE-2026-20973 | Lectura OOB en libimagecodec.quram.so (SMR Jan-2026) | ✅ Parcheado |
| CVE-2026-21045 | Escritura OOB en el análisis TIFF en libimagecodec.media.quram.so (SMR Jul-2026) | ⚠️ Sin parchear para mí |
| CVE-2026-21048 | Escritura OOB en el análisis DNG en libimagecodec.media.quram.so (SMR Jul-2026) | ⚠️ Sin parchear para mí |
| CVE-2026-4775 | Desbordamiento de entero con signo en libtiff 4.6.0 putcontig8bitYCbCr44tile | ⚠️ Sin parchear para mí |
| CVE-2024-7006 | Desreferencia de NULL en libtiff tif_dirinfo.c | ✅ Corregido en 4.6.1 |