NULL POINTER DEREFERENCE Vulnerability in function AP4_List:Find() – Bento4-1.5.1-628
Loginsoft-2018-1062
February 13, 2019
CVE Number
CVE-2019-8382
CWE
CWE-476: NULL Pointer Dereference
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
1.5.1-628
Vulnerability Details
We observed a NULL pointer dereference occurred in function AP4_List: Find () located in Ap4List.h.The same be triggered by sending a crafted file to the mp4dump binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact.
SYNOPSIS
We observed that in function DumpTrackData () in line AP4_Track* track = mp4_file. GetMovie()->GetTrack(track_id) from this it calls to another function AP4_Movie::GetTrack () where this function will get the details of the track_id, here in line if (AP4_SUCCEEDED(m_Tracks.Find(AP4_TrackFinderById(track_id), track))) here track is initialized as NULL, and it calls to another function AP4_TrackFinderById () it will track the id by trackfinder, from this line now it invokes to another function AP4_List: Find (), here when we are sending a crafted input file, in the line Item* item = m_Head where item consists of data & in this particular line it throwing an error which is invalid memory access of m_Head. This results in an error which throws a signal SIGSEGV.
Vulnerable code
template inline AP4_Result AP4_List::Find(const typename Item::Finder& finder, T*& data) const { Item* item = m_Head; while (item) { if (finder.Test(item->m_Data) == AP4_SUCCESS) { data = item->m_Data;
Analysis
ASAN REPORT - ASAN: DEADLYSIGNAL ================================================================= ==10246==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000030 (pc 0x55d0b61aeae7 bp 0x7ffcc696e490 sp 0x7ffcc696e460 T0) ==10246==The signal is caused by a READ memory access. ==10246==Hint: address points to the zero page. #0 0x55d0b61aeae6 in AP4_List::Find(AP4_List::Item::Finder const&, AP4_Track*&) const /home/aceteam/Desktop/packages/Bento4/Source/C++/Core/Ap4List.h:428 #1 0x55d0b61adb79 in AP4_Movie::GetTrack(unsigned int) /home/aceteam/Desktop/packages/Bento4/Source/C++/Core/Ap4Movie.cpp:148 #2 0x55d0b6161f2f in DumpTrackData(char const*, AP4_File&, AP4_Array const&, AP4_ProtectionKeyMap const&) /home/aceteam/Desktop/packages/Bento4/Source/C++/Apps/Mp4Dump/Mp4Dump.cpp:183 #3 0x55d0b616304f in main /home/aceteam/Desktop/packages/Bento4/Source/C++/Apps/Mp4Dump/Mp4Dump.cpp:367 #4 0x7faa6d1a4b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96) #5 0x55d0b61612f9 in _start (/home/aceteam/Desktop/packages/Bento4/builds/mp4dump+0x3082f9) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /home/aceteam/Desktop/packages/Bento4/Source/C++/Core/Ap4List.h:428 in AP4_List::Find(AP4_List::Item::Finder const&, AP4_Track*&) const ==10246==ABORTING
GDB - Program received signal SIGSEGV, Segmentation fault. [ Legend: Modified register | Code | Heap | Stack | String ] ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ registers ]──── $rax : 0x20 $rbx : 0x7fffffffd7e0 → 0x0000555555da9370 → 0x0000555555869846 → push rbp $rcx : 0x0 $rdx : 0x0 $rsp : 0x7fffffffd6f0 → 0x00007fffffffd730 → 0x00000001ffffd750 → 0x0000000000000000 $rbp : 0x7fffffffd720 → 0x00007fffffffd810 → 0x00007fffffffd880 → 0x00007fffffffdc70 → 0x0000555555985150 → push r15 $rsi : 0x7fffffffd7a0 → 0x0000555555da98f0 → 0x00005555558aa0fe → push rbp $rdi : 0x20 $rip : 0x5555558a9ae7 → <AP4_List::Find(AP4_List::Item::Finder+0> mov rax, QWORD PTR [rax+0x10] $r8 : 0x6 $r9 : 0x1e $r10 : 0x7ffff7fbd000 → 0x00007ffff7fee000 → 0x00007ffff716a698 → 0x00007ffff6f09090 → repz ret $r11 : 0x7ffff64a9b97 → mov edi, eax $r12 : 0x7fffffffd740 → 0x0000000041b58ab3 $r13 : 0xffffffffae8 → 0x0000000000000000 $r14 : 0x20 $r15 : 0x7fffffffd740 → 0x0000000041b58ab3 $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $ss: 0x002b $cs: 0x0033 $gs: 0x0000 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ stack ]──── 0x00007fffffffd6f0│+0x00: 0x00007fffffffd730 → 0x00000001ffffd750 → 0x0000000000000000 ← $rsp 0x00007fffffffd6f8│+0x08: 0x00007fffffffd760 → 0x0000000000000000 0x00007fffffffd700│+0x10: 0x00007fffffffd7a0 → 0x0000555555da98f0 → 0x00005555558aa0fe → push rbp 0x00007fffffffd708│+0x18: 0x0000000000000020 0x00007fffffffd710│+0x20: 0x00000001fffffaf8 → 0x0000000000000000 0x00007fffffffd718│+0x28: 0x00007fffffffd7a0 → 0x0000555555da98f0 → 0x00005555558aa0fe → push rbp 0x00007fffffffd720│+0x30: 0x00007fffffffd810 → 0x00007fffffffd880 → 0x00007fffffffdc70 → 0x0000555555985150 → push r15 ← $rbp 0x00007fffffffd728│+0x38: 0x00005555558a8b7a → test eax, eax ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ code:i386:x86-64 ]──── 0x5555558a9adb <AP4_List::Find(AP4_List::Item::Finder+0> mov rdi, rax 0x5555558a9ade <AP4_List::Find(AP4_List::Item::Finder+0> call 0x55555585c180 0x5555558a9ae3 <AP4_List::Find(AP4_List::Item::Finder+0> mov rax, QWORD PTR [rbp-0x18] → 0x5555558a9ae7 <AP4_List::Find(AP4_List::Item::Finder+0> mov rax, QWORD PTR [rax+0x10] 0x5555558a9aeb <AP4_List::Find(AP4_List::Item::Finder+0> mov QWORD PTR [rbp-0x8], rax 0x5555558a9aef <AP4_List::Find(AP4_List::Item::Finder+0> cmp QWORD PTR [rbp-0x8], 0x0 0x5555558a9af4 <AP4_List::Find(AP4_List::Item::Finder+0> je 0x5555558a9c13 <AP4_List::Find(AP4_List::Item::Finder const&, AP4_Track*&) const+361> 0x5555558a9afa <AP4_List::Find(AP4_List::Item::Finder+0> mov rax, QWORD PTR [rbp-0x20] 0x5555558a9afe <AP4_List::Find(AP4_List::Item::Finder+0> mov rdx, rax ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ source:/home/aceteam//Bento4/Source/C++/Core/Ap4List.h+428 ]──── 423 template 424 inline 425 AP4_Result 426 AP4_List::Find(const typename Item::Finder& finder, T*& data) const 427 { // item=0x00007fffffffd718 → [...] → push rbp → 428 Item* item = m_Head; 429 430 while (item) { 431 if (finder.Test(item->m_Data) == AP4_SUCCESS) { 432 data = item->m_Data; 433 return AP4_SUCCESS; ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ threads ]──── [#0] Id 1, Name: "mp4dump", stopped, reason: SIGSEGV ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ trace ]──── [#0] 0x5555558a9ae7 → Name: AP4_List::Find(this=0x20, finder=@0x7fffffffd7a0, data=@0x7fffffffd760) [#1] 0x5555558a8b7a → Name: AP4_Movie::GetTrack(this=0x0, track_id=0x1) [#2] 0x55555585cf30 → Name: DumpTrackData(mp4_filename=0x7fffffffe17b "$POC", mp4_file=@0x7fffffffdb80, tracks_to_dump=@0x7fffffffda80, key_map=@0x7fffffffdac0) [#3] 0x55555585e050 → Name: main(argc=0x6, argv=0x7fffffffdd90) ─────────────────────────────────────────────────────────────────────────────────────────────────
Tested environment
64-bit ubuntu 16.04 LTS
Proof of Concept
./mp4dump --track 1:E791400BC075044176E34136E3C134F35E3513BE430B907B --format text $POC
Timeline
Vendor Disclosure: 02-02-2019
Public Disclosure: 13-02-2019
Credit
Discovered by ACE Team – Loginsoft