/
/
/
CVE-2019-8383: Invalid memory access in adv_png_unfilter_8( ) - advancecomp

CVE-2019-8383: Invalid memory access in adv_png_unfilter_8( ) - advancecomp

Vulnerability Reports
February 13, 2019
Profile Icon

Jason Franscisco

Invalid memory access vulnerability in the function adv_png_unfilter_8( ) - advancecomp-2.1

Loginsoft-2018-1050

February 13, 2019

CVE Number

CVE-2019-8383

CWE

CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer

Product Details

AdvanceCOMP contains recompression utilities for your .zip archives,.png images, .mng video clips and .gz files.

‍URL: Source forge

Vulnerable Versions

2.1

Vulnerability Details

During our research on advancecomp, we found invalid memory address in function adv_png_unfilter_8 ( ) at file png.c. The same can be triggered by sending a crafted abc file to the binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact when a victim opens a specially crafted file.

SYNOPSIS

As per our research we observed that the vulnerability exists in function adv_png_unfilter_8( ) at file png.c . The function adv_png_read_rns( ),which reads an image from memory which is in png format and invokes the function adv_png_read_ihdr (),which reads a part of chunk image from PNG_CN_IHDR to the chunk from the main in PNG_CN_IEND . This function invokes adv_png_unfilter_8( ) which unfilters a 8 bit image of width, height, data and size of row. When a crafted file is passed to the binary advpng in function adv_png_unfilter_8( ) at unsigned char f = *p++;p += width;The value of width is being assigned to p. The value of f is 0 and p is having a value at address while incrementing the p value the vulnerability is being triggered as invalid memory access.

Vulnerable code

for(i=0;i less than height;++i) {
        unsigned char f = *p++;
          if (f == 0) { /* none */
            p += width;
}
  
Analysis

277            unsigned char f = *p++;
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ registers ]────
$rax   : 0x80661b7d        
$rbx   : 0x0               
$rcx   : 0x8000008d        
$rdx   : 0x80661b7e        
$rsp   : 0x7fffffffd7d0      →  0x00007fffffffd910  →  0x00007fffffffd9e0  →  0x00007fffffffda90  →  0x00007fffffffdb70  →  0x00007fffffffdc60  →  0x00007fffffffdce0  →  0x00007fffffffddb0
$rbp   : 0x7fffffffd7d0      →  0x00007fffffffd910  →  0x00007fffffffd9e0  →  0x00007fffffffda90  →  0x00007fffffffdb70  →  0x00007fffffffdc60  →  0x00007fffffffdce0  →  0x00007fffffffddb0
$rsi   : 0x78              
$rdi   : 0x8000008c        
$rip   : 0x40c5c7            →   movzx eax, BYTE PTR [rax]
$r8    : 0x65ffa0            →  0x0000000000000000
$r9    : 0x1               
$r10   : 0x8b8             
$r11   : 0x7ffff6fca4f0      →   push r13
$r12   : 0x402fe0            →   xor ebp, ebp
$r13   : 0x7fffffffdee0      →  0x0000000000000005
$r14   : 0x0               
$r15   : 0x0               
$eflags: [CARRY parity ADJUST zero SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$fs: 0x0000  $cs: 0x0033  $gs: 0x0000  $es: 0x0000  $ds: 0x0000  $ss: 0x002b  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ stack ]────
0x00007fffffffd7d0│+0x00: 0x00007fffffffd910  →  0x00007fffffffd9e0  →  0x00007fffffffda90  →  0x00007fffffffdb70  →  0x00007fffffffdc60  →  0x00007fffffffdce0  →  0x00007fffffffddb0     ← $rsp, $rbp
0x00007fffffffd7d8│+0x08: 0x000000000040d8d0  →   jmp 0x40db14 
0x00007fffffffd7e0│+0x10: 0xb7b6b5b4b3b2b1b0
0x00007fffffffd7e8│+0x18: 0x000000000065fe00  →  0x780000008c000080
0x00007fffffffd7f0│+0x20: 0x000000000065fc60  →  0x00007fff00000001
0x00007fffffffd7f8│+0x28: 0x00007fffffffda50  →  0x8000008d00000000
0x00007fffffffd800│+0x30: 0x00007fffffffda68  →  0x0000000000000000
0x00007fffffffd808│+0x38: 0x00007fffffffda4c  →  0x000000000000007e ("~"?)
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ code:i386:x86-64 ]────
     0x40c5b7  test   BYTE PTR [rdx], 0x0
     0x40c5ba  add    BYTE PTR [rax-0x75], cl
     0x40c5bd  rex.RB movabs al, ds:0xa055894801508d48
→   0x40c5c7  movzx  eax, BYTE PTR [rax]
     0x40c5ca  mov    BYTE PTR [rbp-0x41], al
     0x40c5cd  cmp    BYTE PTR [rbp-0x41], 0x0
     0x40c5d1  jne    0x40c5df 
     0x40c5d3  mov    eax, DWORD PTR [rbp-0x54]
     0x40c5d6  add    QWORD PTR [rbp-0x60], rax
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ source:lib/png.c+277 ]────
    272     void adv_png_unfilter_8(unsigned width, unsigned height, unsigned char* p, unsigned line)
    273     {
    274         unsigned i, j;
    275     
    276         for(i=0;i less than height;++i) {
        // f=0x0, p=0x00007fffffffd770  →  0x0000000080661b7e
→  277             unsigned char f = *p++;
    278     
    279             if (f == 0) { /* none */
    280                 p += width;
    281             } else if (f == 1) { /* sub */
    282                 ++p;
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ threads ]────
[#0] Id 1, Name: "advpng", stopped, reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x40c5c7 → Name: adv_png_unfilter_8(width=0x8000008c, height=0x78, p=0x80661b7e , line=0x8000008d)
[#1] 0x40d8d0 → Name: adv_png_read_ihdr(pix_width=0x7fffffffda44, pix_height=0x7fffffffda48, pix_pixel=0x7fffffffda40, dat_ptr=0x7fffffffda58, dat_size=0x7fffffffda3c, pix_ptr=0x7fffffffda70, pix_scanline=0x7fffffffda54, pal_ptr=0x7fffffffda60, pal_size=0x7fffffffda4c, rns_ptr=0x7fffffffda68, rns_size=0x7fffffffda50, f=0x65fc60, data=0x65fe00 "\200", data_size=0xd)
[#2] 0x40dc94 → Name: adv_png_read_rns(pix_width=0x7fffffffda44, pix_height=0x7fffffffda48, pix_pixel=0x7fffffffda40, dat_ptr=0x7fffffffda58, dat_size=0x7fffffffda3c, pix_ptr=0x7fffffffda70, pix_scanline=0x7fffffffda54, pal_ptr=0x7fffffffda60, pal_size=0x7fffffffda4c, rns_ptr=0x7fffffffda68, rns_size=0x7fffffffda50, f=0x65fc60)
[#3] 0x4037dd → Name: convert_f(f_in=0x65fc60, f_out=0x65fd30)
[#4] 0x403a62 → Name: convert_inplace(path="$POC")
[#5] 0x404209 → Name: rezip_single(file="id:000000,sig:11,src:000000,op:flip1,pos:16", total_0=@0x7fffffffdc90, total_1=@0x7fffffffdc98)
[#6] 0x4045a1 → Name: rezip_all(argc=0x1, argv=0x7fffffffdf08)
[#7] 0x404df0 → Name: process(argc=0x5, argv=0x7fffffffdee8)
[#8] 0x404fba → Name: main(argc=0x5, argv=0x7fffffffdee8)
  
Tested environment

64-bit ubuntu 16.04 LTS

Proof of Concept

- ./advpng -z -1 –f $POC

Timeline

Vendor Disclosure: 03-01-2019

Public Disclosure: 13-02-2019

Credit

Discovered by ACE Team - Loginsoft

Explore Cybersecurity Platforms

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.

Discover Lovi
Stay Ahead

Get the Latest Cybersecurity Insights

Security research, threat intelligence, vulnerability updates, product news, and expert insights, delivered directly to your inbox. Stay informed. Stay secure.