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