Null pointer Dereference vulnerability in crop_page() – podofo 0.9.6
November 19, 2018
CVE Number
–
CWE
CWE-476: NULL Pointer Dereference
Product Details
PoDoFo is a library to work with the PDF file format.
URL: https://sourceforge.net/projects/podofo/
Vulnerable Versions
0.9.6-trunk r1952
Vulnerability Details
During our research on the podofo, a NULL pointer dereference vulnerability is discovered in the pdofo (0.9.6 – Trunk r1952). The same be triggered by sending a crafted pdf file to the podofocrop binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact.
SYNOPSIS
As per our research, the vulnerability exits in function crop_page()
in podofocrop.cpp.
Source code : void crop_page(PdfPage* pPage, const PdfRect & rCropBox) { PdfVariant var; /* printf("%f %f %f %f\n", rCropBox.GetLeft(), rCropBox.GetBottom(), rCropBox.GetWidth(), rCropBox.GetHeight()); */ rCropBox.ToVariant( var ); pPage->GetObject()->GetDictionary().AddKey( PdfName("MediaBox"), var ); }
When a crafted pdf is passed to the binary, In the pPage->GetObject()->GetDictionary().AddKey( PdfName("MediaBox"), var );
. This issue is due to the function GetObject()
being called by a NULL pointer object which is pPage
. We observed that the value of pPage
at this point is 0x0 which cause the Null Dereference vulnerability.
Analysis
DEBUG: GDB : [ Legend: Modified register | Code | Heap | Stack | String] ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── $eax : 0x0 $ebx : 0x2 $ecx : 0x0 $edx : 0x8 $esp : 0xbffff388 → 0xbffff418 → 0xbffff568 → 0x00000000 $ebp : 0xbffff388 → 0xbffff418 → 0xbffff568 → 0x00000000 $esi : 0xb74e8000 → 0x001b1db0 $edi : 0xb74e8000 → 0x001b1db0 $eip : 0x080f7253 → mov eax, DWORD PTR [ebp+0x8] $eflags: [carry parity ADJUST zero SIGN trap INTERRUPT direction overflow resume virtualx86 IDENTIFICATION] $cs: 0x0073 $ss: 0x007b $ds: 0x007b $es: 0x007b $fs: 0x0000 $gs: 0x0033 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0xbffff388│+0x0000: 0xbffff418 → 0xbffff568 → 0x00000000 ← $esp, $ebp 0xbffff38c│+0x0004: 0x080f5e6b → add esp, 0x10 0xbffff390│+0x0008: 0x00000000 0xbffff394│+0x000c: 0x081c281b → "MediaBox" 0xbffff398│+0x0010: 0x00000005 0xbffff39c│+0x0014: 0x00000000 0xbffff3a0│+0x0018: 0x00000000 0xbffff3a4│+0x001c: 0xb5a01420 → 0x2a000006 → 0x00000000 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── 0x80f724f nop 0x80f7250 push ebp 0x80f7251 mov ebp, esp → 0x80f7253 mov eax, DWORD PTR [ebp+0x8] 0x80f7256 mov eax, DWORD PTR [eax+0x4] 0x80f7259 pop ebp 0x80f725a ret 0x80f725b nop 0x80f725c <std::vector push ebp ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:/home/loginsoft/ACE/sources/pruthvi/podofo1952/podofo-code-r1952-podofo-trunk/src/doc/PdfElement.h+180 ──── 175 // ----------------------------------------------------- 176 // 177 // ----------------------------------------------------- 178 inline PdfObject* PdfElement::GetObject() 179 { → 180 return m_pObject; 181 } 182 183 // ----------------------------------------------------- 184 // 185 // ----------------------------------------------------- ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "podofocrop", stopped, reason: BREAKPOINT ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── [#0] 0x80f7253 → PoDoFo::PdfElement::GetObject(this=0x0) [#1] 0x80f5e6b → crop_page(pPage=0x0, rCropBox=@0xb5001760) [#2] 0x80f66ba → main(argc=0x3, argv=0xbffff614) ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── gef➤ p m_pObject Cannot access memory at address 0x4 gef➤ p $eax+0x4 $19 = 0x4 gef➤ x/w $eax+0x4 0x4: Cannot access memory at address 0x4
Proof of Concept
podofocrop $POC out.pdf
Mitigation
This issue can be prevented by doing a NULL check over the value of ‘pPage’ in the function crop_page() of podofocrop.cpp
Timeline
Vendor Disclosure: 2018-11-19
Public Disclosure:
Credit
Discovered by ACE Team – Loginsoft