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