Menu

#32 Null pointer dereference vulnerability in PdfTranslator::setTarget()

SVN TRUNK
closed
security (37)
2019-02-11
2018-11-15
Ace Team
No

What is the vulnerability?
A NULL pointer dereference vulnrability is discovered in the pdofo (0.9.6 - Trunk r1949 ) . The same be triggered by sending a crafted pdf file to the podofoimpose binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact.

Version - 0.9.6 -Trunk r1949

Tested environment - 32-bit ubuntu 16.04 LTS

Command - podofoimpose $POC test.pdf native

vulnerable code

for (int i = 0; i < pcount ; ++i )  
{  
PdfPage * page = sourceDoc->GetPage ( i );  
PdfMemoryOutputStream outMemStream ( 1 );  
PdfXObject *xobj = new PdfXObject ( page->GetMediaBox(), targetDoc );  
if ( page->GetContents()->HasStream() )  
{  
page->GetContents()->GetStream()->GetFilteredCopy ( &outMemStream );  
} 

Synopsis
As per our research, the vulnerability exits in functionPdfTranslator::setTarget in pdftranslator.cpp. The pointer page, contains the details of a pdf page.

Gdb :

gef➤  p page 
$53 = (PoDoFo::PdfPage *) 0x82a2d30 
gef➤  p *page 
$56 = { 
  <PoDoFo::PdfElement> = { 
    _vptr.PdfElement = 0x822b4c0 <vtable for PoDoFo::PdfPage+8>, 
    m_pObject = 0x82a5f78 
  }, 
  <PoDoFo::PdfCanvas> = { 
    _vptr.PdfCanvas = 0x822b504 <vtable for PoDoFo::PdfPage+76> 
  }, 
  members of PoDoFo::PdfPage: 
  m_pContents = 0x82a7870, 
  m_pResources = 0x82a8870, 
  m_mapAnnotations = std::map with 0 elements, 
  m_mapAnnotationsDirect = std::map with 0 elements 

In line PdfXObject *xobj = new PdfXObject ( page->GetMediaBox(), targetDoc ), While storing the pdf objects in xobj, if a crafted pdf file is supplied to the binary , a NULL dereference issue is created as the page pointer points to an non-existing address 0x0 .

DEBUG

GDB : 

259                                     PdfXObject *xobj = new PdfXObject ( page->GetMediaBox(), targetDoc ); 
1: page = (PoDoFo::PdfPage *) 0x0 
[ Legend: Modified register | Code | Heap | Stack | String ] 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── 
$eax   : 0x0 
$ebx   : 0x082a9de4    0x082aa7f0    0x08219b78    0x0813d594    <PoDoFo::PdfObject::~PdfObject()+0> push ebp 
$ecx   : 0x3 
$edx   : 0x082aaef0    0x00000000 
$esp   : 0xbffff470    0xb7bab000    0x00172664 
$ebp   : 0xbffff528    0xbffff568    0x00000000 
$esi   : 0xbffff4d8    0x00000000 
$edi   : 0xb7a16000    0x001b1db0 
$eip   : 0x0811bd62    <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> mov eax, DWORD PTR [ebp-0x90] 
$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 ──── 
0xbffff470+0x0000: 0xb7bab000    0x00172664     $esp 
0xbffff474+0x0004: 0xb7b08756    <__gnu_cxx::stdio_sync_filebuf<char,+0> add ebx, 0xa28aa 
0xbffff478+0x0008: 0x08293b30    0x08293b38    "test" 
0xbffff47c+0x000c: 0x082a1c48    0x082a1e10    0x0822aa54    0x081727a6    <PoDoFo::PdfMemDocument::~PdfMemDocument()+0> push ebp 
0xbffff480+0x0010: 0x08293a40    0xb7ba9c68    0xb7b2d9e0    <std::basic_ostream<char,+0> push ebx 
0xbffff484+0x0014: 0x082a9348    0x00000020 
0xbffff488+0x0018: 0x00000001 
0xbffff48c+0x001c: 0x00000001 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── 
    0x811bd59 <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> push   eax 
    0x811bd5a <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> call   0x813fa66 <PoDoFo::PdfMemoryOutputStream::PdfMemoryOutputStream(int)> 
    0x811bd5f <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> add    esp, 0x10 
  0x811bd62 <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> mov    eax, DWORD PTR [ebp-0x90] 
    0x811bd68 <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> mov    eax, DWORD PTR [eax] 
    0x811bd6a <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> add    eax, 0x18 
    0x811bd6d <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> mov    eax, DWORD PTR [eax] 
    0x811bd6f <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> lea    edx, [ebp-0x50] 
    0x811bd72 <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char,+0> sub    esp, 0x8 
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:/home/loginsoft/podofo-code-r1949-podofo-trunk/tools/podofoimpose/pdftranslator.cpp+259 ──── 
    254                         for ( int i = 0; i < pcount ; ++i ) 
    255                         { 
    256                                 PdfPage * page = sourceDoc->GetPage ( i ); 
    257                                 PdfMemoryOutputStream outMemStream ( 1 ); 
    258 
                // page=0xbffff498    0x00000000, xobj=0xbffff49c    [...]    <PoDoFo::PdfXObject::~PdfXObject()+0> push ebp 
  259                                 PdfXObject *xobj = new PdfXObject ( page->GetMediaBox(), targetDoc ); 
    260                                 if ( page->GetContents()->HasStream() ) 
    261                                 { 
    262                                         page->GetContents()->GetStream()->GetFilteredCopy ( &outMemStream ); 
    263                                 } 
    264                                 else if ( page->GetContents()->IsArray() ) 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── 
[#0] Id 1, Name: "podofoimpose", stopped, reason: BREAKPOINT 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── 
[#0] 0x811bd62  PoDoFo::Impose::PdfTranslator::setTarget(this=0x82a1c48, target="test") 
[#1] 0x8119af1  main(argc=0x4, argv=0xbffff614) 

gef  p page 
$58 = (PoDoFo::PdfPage *) 0x0 
gef  p *page 
Cannot access memory at address 0x0 
gef  i r 
eax            0x0      0x0 
ecx            0x3      0x3 
edx            0x82aaef0        0x82aaef0 
ebx            0x82a9de4        0x82a9de4 
esp            0xbffff470       0xbffff470 
ebp            0xbffff528       0xbffff528 
esi            0xbffff4d8       0xbffff4d8 
edi            0xb7a16000       0xb7a16000 
eip            0x811bd62        0x811bd62 <PoDoFo::Impose::PdfTranslator::setTarget(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)+320> 
eflags         0x200282 [ SF IF ID ] 
cs             0x73     0x73 
ss             0x7b     0x7b 
ds             0x7b     0x7b 
es             0x7b     0x7b 
fs             0x0      0x0 
gs             0x33     0x33 

gef  bt
#0  0x0811bd68 in PoDoFo::Impose::PdfTranslator::setTarget (this=0x82a1c70, target="test.pdf") at /home/loginsoft/podofo-code-r1949-podofo-trunk/tools/podofoimpose/pdftranslator.cpp:259
#1  0x08119af1 in main (argc=0x4, argv=0xbffff604) at /home/loginsoft/podofo-code-r1949-podofo-trunk/tools/podofoimpose/podofoimpose.cpp:108
1 Attachments
POC

Related

Tickets: #1

Discussion

  • Matthew Brincke

    Matthew Brincke - 2018-11-15
    • labels: --> security
    • status: open --> pending
    • assigned_to: Matthew Brincke
     
  • Matthew Brincke

    Matthew Brincke - 2018-11-15

    As this is clearly a security issue, the label "security" (missing before) is added and I've set it as "pending" even though I haven't reproduced it yet (but will try shortly) because it's so clearly explained here.

     
  • Matthew Brincke

    Matthew Brincke - 2018-11-16
    • status: pending --> closed
     
  • Matthew Brincke

    Matthew Brincke - 2018-11-16

    Thanks for the detailed report. Per my test the change I committed to svn r1950 fixes this issue, so I'm closing it.

     
  • Mattia Rizzolo

    Mattia Rizzolo - 2019-02-11

    FTR, this was given CVE-2018-19532