CVE-2019-11024: Infinite loop in function load_pnm( ) – Libsixel – 1.8.2

Infinite loop in function load_pnm( ) – Libsixel – 1.8.2

Loginsoft-2019-1112

8 April, 2019

CVE Number

CVE-2019-11024

CWE

CWE – 20 : Improper Input Validation

Product Details

A SIXEL encoder/decoder implementation derived from kmiya’s sixel. This package provides encoder/decoder implementation for DEC SIXEL graphics, and some converter programs.
URL: https://github.com/saitoha/libsixel

Vulnerable Versions

1.8.2

Vulnerability Details

As per our research on libsixel we found an infinite loop generating recursively at function load_pnm( ) at file frompnm.c which can lead to a denial of service attack

SYNOPSIS

During our research on libsixel we found an infinite loop generating at function load_pnm () at file frompnm.c The function load_pnm( ) which loads sixelstatus and when a crafted file is passed to the binary there is an infinite while loop generating recursively and enters into function pnm_get_line( ) at this line of code while (line[0] == ‘#’); where, the value of line[O] is 0x0 which does not satisfy the condition and recursively generates an infinite loop which can lead to a denial of service.

vulnerable Source code
while (*s == '\0') {
                       if (p >= end) {
                           break;
                       }
                       p = pnm_get_line(p, end, tmp);
                       s = tmp;
                   } 

Analysis

DEBUG:
GDB :

Gdb:  [ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x00007fffffffd160  →  0x43434380f0314300
$rbx   : 0x00007fffffffd2a0  →  0x00007fffffffd660  →  0x0000000000000000
$rcx   : 0x00007fffffffd100  →  0x0000000000000000
$rdx   : 0x0               
$rsp   : 0x00007fffffffcf50  →  0x000060400000dfd0  →  0xbebebebe00000003
$rbp   : 0x00007fffffffd2c0  →  0x00007fffffffd690  →  0x00007fffffffd780  →  0x00007fffffffd7f0  →  0x00007fffffffddb0  →  0x0000000000401c00  →   push r15
$rsi   : 0x0               
$rdi   : 0x0               
$rip   : 0x00007ffff6c08ec1  →   mov rax, QWORD PTR [rbp-0x2f0]
$r8    : 0x3               
$r9    : 0x184d0           
$r10   : 0x2b1             
$r11   : 0x00007ffff6ef6ab0  →   push rbp
$r12   : 0x00000ffffffff9fc  →  0x0000000000000000
$r13   : 0x00007fffffffcfe0  →  0x0000000041b58ab3
$r14   : 0x00007fffffffcfe0  →  0x0000000041b58ab3
$r15   : 0x0               
$eflags: [CARRY PARITY ADJUST zero SIGN trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffcf50│+0x0000: 0x000060400000dfd0  →  0xbebebebe00000003     ← $rsp
0x00007fffffffcf58│+0x0008: 0x000060700000dfd4  →  0x0000000000000003
0x00007fffffffcf60│+0x0010: 0x000060700000dfd0  →  0x00000003ffffffff  →  0x0000000000000000
0x00007fffffffcf68│+0x0018: 0x0000000000000000
0x00007fffffffcf70│+0x0020: 0x000060700000dfcc  →  0xffffffff00000000
0x00007fffffffcf78│+0x0028: 0x000060700000dfc8  →  0x0000000000000000
0x00007fffffffcf80│+0x0030: 0x000060700000dfb8  →  0x000060300000efb0  →  0xffff000000000000
0x00007fffffffcf88│+0x0038: 0x000060400000dfd0  →  0xbebebebe00000003
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x7ffff6c08eac   mov    QWORD PTR [rbp-0x328], rax
   0x7ffff6c08eb3   lea    rax, [rbx-0x140]
   0x7ffff6c08eba   mov    QWORD PTR [rbp-0x2f0], rax
→ 0x7ffff6c08ec1   mov    rax, QWORD PTR [rbp-0x2f0]
   0x7ffff6c08ec8   mov    rdx, rax
   0x7ffff6c08ecb   shr    rdx, 0x3
   0x7ffff6c08ecf   add    rdx, 0x7fff8000
   0x7ffff6c08ed6   movzx  edx, BYTE PTR [rdx]
   0x7ffff6c08ed9   test   dl, dl
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:frompnm.c+229 ────
    224         for (y = 0 ; y < height ; y++) {
    225             for (x = 0 ; x < width ; x++) {
    226                 b = (maps == 2 ? 3 : 1);
    227                 for (i = 0 ; i = end) {
    231                                 break;
    232                             }
    233                             p = pnm_get_line(p, end, tmp);
    234                             s = tmp;
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "img2sixel", stopped, reason: SIGINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff6c08ec1 → load_pnm(p=0x62d00000a427 "\027", '\276' , length=0x28, allocator=0x60400000dfd0, result=0x60700000dfb8, psx=0x60700000dfc8, psy=0x60700000dfcc, ppalette=0x0, pncolors=0x60700000dfd0, ppixelformat=0x60700000dfd4)
[#1] 0x7ffff6c077b3 → load_with_builtin(pchunk=0x60300000efe0, fstatic=0x0, fuse_palette=0x0, reqcolors=0x100, bgcolor=0x0, loop_control=0x1, fn_load=0x7ffff6c16ad6 , context=0x610000007f40)
[#2] 0x7ffff6c0836f → sixel_helper_load_image_file(filename=0x7fffffffe2b1 "hang10", fstatic=0x0, fuse_palette=0x0, reqcolors=0x100, bgcolor=0x0, loop_control=0x1, fn_load=0x7ffff6c16ad6 , finsecure=0x1, cancel_flag=0x606ac0 , context=0x610000007f40, allocator=0x60400000dfd0)
[#3] 0x7ffff6c16f5b → sixel_encoder_encode(encoder=0x610000007f40, filename=0x7fffffffe2b1 "hang10")
[#4] 0x4019ce → main(argc=0xd, argv=0x7fffffffde98)
Proof of Concept

./img2sixel -78eIkiugv -w 4 -h 8 -q auto -l force -o out $POC
Vendor Disclosure: 2019-3-28
Public Disclosure: 2019-4-9

Credit

Discovered by ACE Team – Loginsoft