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 less than 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; iless than 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