CVE-2019-9544: Out of bounds write in function AP4_CttsTableEntry::AP4_CttsTableEntry() – Bento4-1.5.1.0

Out of bound write in function AP4_CttsTableEntry::AP4_CttsTableEntry() – Bento4-1.5.1.0

Loginsoft-2019-1101

February 13, 2019

CVE Number

CVE-2019-9544

CWE

CWE-787: Out-of-bounds Write

Product Details

Bento4/AP4 is a C++ class library designed to read and write ISO-MP4 files. Where Aac2Mp4 converts an AAC ADTS file into an MP4 file.
URL: https://github.com/axiomatic-systems/Bento4.git

Vulnerable Versions

4-1.5.1.0

Vulnerability Details

We observed a Out of bounds write occurred in AP4_CttsTableEntry::AP4_CttsTableEntry() located in Ap4Array.h.The same be triggered by sending a crafted file to the mp42hls binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact.

SYNOPSIS

In progress

Vulnerable code
AP4_Result result = EnsureCapacity(item_count);
if (AP4_FAILED(result)) return result;

      // construct the new items
     for (unsigned int i=m_ItemCount; i<item_count; i++) {
               // i=0x27ae
         new ((void*)&m_Items[i]) T();
      }
     m_ItemCount = item_count;
     return AP4_SUCCESS;
 }
Analysis

Debug in Linux
GDB

AP4_Array::SetItemCount
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:/home/loginsoft/ACE/sources/himanshu_sources/Bento4/Source/C++/Core/Ap4Array.h+215 ────
   210      AP4_Result result = EnsureCapacity(item_count);
   211      if (AP4_FAILED(result)) return result;
   212
   213      // construct the new items
   214      for (unsigned int i=m_ItemCount; i<item_count; i++) {
               // i=0x27ae
→  215          new ((void*)&m_Items[i]) T();
   216      }
   217      m_ItemCount = item_count;
   218      return AP4_SUCCESS;
   219  }
   220
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "mp42hls", stopped, reason: SIGSEGV
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x810429f → AP4_Array::SetItemCount(this=0x8165278, item_count=0x80000001)
[#1] 0x8103d92 → AP4_SbgpAtom::AP4_SbgpAtom(this=0x8165250, size=0x1c, version=0x0, flags=0x0, stream=@0x8159ea0)
[#2] 0x8103bf5 → AP4_SbgpAtom::Create(size=0x1c, stream=@0x8159ea0)
[#3] 0x80f59da → AP4_AtomFactory::CreateAtomFromStream(this=0xbffff1c4, stream=@0x8159ea0, type=0x73626770, size_32=0x1c, size_64=0x1c, atom=@0xbfffe72c)
[#4] 0x80f412a → AP4_AtomFactory::CreateAtomFromStream(this=0xbffff1c4, stream=@0x8159ea0, bytes_available=@0xbfffe730, atom=@0xbfffe72c)
[#5] 0x80a4cd5 → AP4_ContainerAtom::ReadChildren(this=0x815ea10, atom_factory=@0xbffff1c4, stream=@0x8159ea0, size=0x4a40)
[#6] 0x80a4a44 → AP4_ContainerAtom::AP4_ContainerAtom(this=0x815ea10, type=0x7374626c, size=0x4a48, force_64=0x0, stream=@0x8159ea0, atom_factory=@0xbffff1c4)
[#7] 0x80a47e5 → AP4_ContainerAtom::Create(type=0x7374626c, size=0x4a48, is_full=0x0, force_64=0x0, stream=@0x8159ea0, atom_factory=@0xbffff1c4)
[#8] 0x80f5bbf → AP4_AtomFactory::CreateAtomFromStream(this=0xbffff1c4, stream=@0x8159ea0, type=0x7374626c, size_32=0x4a48, size_64=0x4a48, atom=@0xbfffe93c)
[#9] 0x80f412a → AP4_AtomFactory::CreateAtomFromStream(this=0xbffff1c4, stream=@0x8159ea0, bytes_available=@0xbfffe940, atom=@0xbfffe93c)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

ASAN REPORT

WARNING: forcing version to 4 in order to support single file output 
================================================================= 
==9911==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb4303d10 at pc 0x08187f87 bp 0xbfffd008 sp 0xbfffcff8 
WRITE of size 4 at 0xb4303d10 thread T0 
    #0 0x8187f86 in AP4_CttsTableEntry::AP4_CttsTableEntry() /Bento4/Source/C++/Core/Ap4CttsAtom.h:51 
    #1 0x8188428 in AP4_Array::SetItemCount(unsigned int) /Bento4/Source/C++/Core/Ap4Array.h:215 
    #2 0x8187441 in AP4_CttsAtom::AP4_CttsAtom(unsigned int, unsigned char, unsigned int, AP4_ByteStream&) /Bento4/Source/C++/Core/Ap4CttsAtom.cpp:79 
    #3 0x81870aa in AP4_CttsAtom::Create(unsigned int, AP4_ByteStream&) /Bento4/Source/C++/Core/Ap4CttsAtom.cpp:52 
    #4 0x8196e9a in AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream&, unsigned int, unsigned int, unsigned long long, AP4_Atom*&) /Bento4/Source/C++/Core/Ap4AtomFactory.cpp:469 
    #5 0x81950ee in AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream&, unsigned long long&, AP4_Atom*&) /Bento4/Source/C++/Core/Ap4AtomFactory.cpp:231 
    #6 0x80c376f in AP4_ContainerAtom::ReadChildren(AP4_AtomFactory&, AP4_ByteStream&, unsigned long long) /Bento4/Source/C++/Core/Ap4ContainerAtom.cpp:194 
    #7 0x80c31a1 in AP4_ContainerAtom::AP4_ContainerAtom(unsigned int, unsigned long long, bool, AP4_ByteStream&, AP4_AtomFactory&) /Bento4/Source/C++/Core/Ap4ContainerAtom.cpp:139 
    #8 0x80c2c79 in AP4_ContainerAtom::Create(unsigned int, unsigned long long, bool, bool, AP4_ByteStream&, AP4_AtomFactory&) /Bento4/Source/C++/Core/Ap4ContainerAtom.cpp:88 
    #9 0x81987d0 in AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream&, unsigned int, unsigned int, unsigned long long, AP4_Atom*&) /Bento4/Source/C++/Core/Ap4AtomFactory.cpp:774 
    #10 0x81950ee in AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream&, unsigned long long&, AP4_Atom*&) /Bento4/Source/C++/Core/Ap4AtomFactory.cpp:231 
    #11 0x80c376f in AP4_ContainerAtom::ReadChildren(AP4_AtomFactory&, AP4_ByteStream&, unsigned long long) /Bento4/Source/C++/Core/Ap4ContainerAtom.cpp:194 
    #12 0x80c31a1 in AP4_ContainerAtom::AP4_ContainerAtom(unsigned int, unsigned long long, bool, AP4_ByteStream&, AP4_AtomFactory&) /Bento4/Source/C++/Core/Ap4ContainerAtom.cpp:139 
    #13 0x80c2c79 in AP4_ContainerAtom::Create(unsigned int, unsigned long long, bool, bool, AP4_ByteStream&, AP4_AtomFactory&) /Bento4/Source/C++/Core/Ap4ContainerAtom.cpp:88 
    #14 0x81987d0 in AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream&, unsigned int, unsigned int, unsigned long long, AP4_Atom*&) /Bento4/Source/C++/Core/Ap4AtomFactory.cpp:774 
SUMMARY: AddressSanitizer: heap-buffer-overflow /Bento4/Source/C++/Core/Ap4CttsAtom.h:51 AP4_CttsTableEntry::AP4_CttsTableEntry() 
Shadow bytes around the buggy address: 
  0x36860750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x36860760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x36860770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x36860780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x36860790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
=>0x368607a0: 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368607b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368607c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368607d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368607e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x368607f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
Shadow byte legend (one shadow byte represents 8 application bytes): 
  Addressable:           00 
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa 
  Heap right redzone:      fb 
  Freed heap region:       fd 
  Stack left redzone:      f1 
  Stack mid redzone:       f2 
  Stack right redzone:     f3 
  Stack partial redzone:   f4 
  Stack after return:      f5 
  Stack use after scope:   f8 
  Global redzone:          f9 
  Global init order:       f6 
  Poisoned by user:        f7 
  Container overflow:      fc 
  Array cookie:            ac 
  Intra object redzone:    bb 
  ASan internal:           fe 
==9911==ABORTING 

Debug in windows

STACK_TEXT:   
004be750 000d6b2d 0074f000 00000551 00000000 Mp42Hls!AP4_CttsTableEntry::AP4_CttsTableEntry+0x11 
004be76c 000d60e3 40000382 15981e17 004be928 Mp42Hls!AP4_Array::SetItemCount+0xbd 
004be7bc 000d668b 00001c20 00000000 00000000 Mp42Hls!AP4_CttsAtom::AP4_CttsAtom+0xa3 
004be808 000a1fb9 00001c20 00749810 1598109f Mp42Hls!AP4_CttsAtom::Create+0xab 
004be934 000a08dd 00749810 63747473 00001c20 Mp42Hls!AP4_AtomFactory::CreateAtomFromStream+0x14c9 
004be9e8 000ae0b9 00749810 004bea08 004bea18 Mp42Hls!AP4_AtomFactory::CreateAtomFromStream+0x26d 
FAILURE_BUCKET_ID:  INVALID_POINTER_WRITE_c0000005_Mp42Hls.exe!AP4_CttsTableEntry::AP4_CttsTableEntry 
  
BUCKET_ID:  APPLICATION_FAULT_INVALID_POINTER_WRITE_Mp42Hls!AP4_CttsTableEntry::AP4_CttsTableEntry+11 
  
ExceptionCode: c0000005 (Access violation) 
FAULTING_SOURCE_FILE:  \bento4-master\source\c++\core\ap4cttsatom.h 
FAILURE_FUNCTION_NAME:  AP4_CttsTableEntry::AP4_CttsTableEntry 
Registers: 
eax=0074f000 ebx=7efde000 ecx=0074f000 edx=00000001 esi=004be954 edi=004be7b0 
eip=000d62f1 esp=004be74c ebp=004be750 iopl=0         nv up ei pl nz na po nc 
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202 
Tested environment

64-bit ubuntu 16.04 LTS

Proof of Concept

Windows –
mp42hls.exe --hls-version 3 --pmt-pid 0x100 --video-pid 0x102 --video-track-id 1 --segment-duration 6 --segment-duration-threshold 15 --pcr-offset 10000 --index-filename stream.m3u8 --segment-filename-template stream.mp4 --output-single-file $POC
Linux –
mp42hls --hls-version 3 --pmt-pid 0x100 --video-pid 0x102 --video-track-id 1 --segment-duration 6 --segment-duration-threshold 15 --pcr-offset 10000 --index-filename stream.m3u8 --segment-filename-template stream.mp4 --output-single-file $POC

Timeline

Vendor Disclosure: 2019-2-28
Public Disclosure: 2019-3-2

Credit

Discovered by ACE Team – Loginsoft