Null pointer dereference vulnerability in crop_page() – podofo 0.9.6

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