Foxit PDF Reader 1.0.1.0925 – CFX_BaseSegmentedArray::IterateIndex Memory Corruption

  • 作者: Google Security Research
    日期: 2016-06-13
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/39944/
  • Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=742
    
    We have identified the following memory corruption vulnerability in Foxit PDF Reader (version 1.0.1.0925 for Linux 64-bit), when started with a specially crafted PDF file in the following way:
    
    $ DISPLAY=:1 FoxitReader /path/to/poc/file.pdf
    
    The DISPLAY=:1 environment variable is set due to the fact that we are testing the application with a virtual X server (Xvfb), but the issue should be equally reproducible with the program started with standard display settings, too.
    
    An example excerpt from the crash log is as follows:
    
    --- cut ---
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000000aab96c in CFX_BaseSegmentedArray::IterateIndex(int, int&, void**, int (*)(void*, void*), void*) const ()
    (gdb) where
    #00x0000000000aab96c in CFX_BaseSegmentedArray::IterateIndex(int, int&, void**, int (*)(void*, void*), void*) const ()
    #10x0000000000aab9dc in CFX_BaseSegmentedArray::Iterate(int (*)(void*, void*), void*) const ()
    #20x0000000000ab1a99 in CFX_CMapByteStringToPtr::Lookup(CFX_ByteStringC const&, void*&) const ()
    #30x00000000007db5df in CPDF_Dictionary::KeyExist(CFX_ByteStringC const&) const ()
    #40x000000000070e6a6 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
    #50x000000000070e6e3 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
    #60x000000000070f986 in CBMTreeCtrl::on_ItemExpanded(QTreeWidgetItem*) ()
    #70x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
    #80x00007ffff7722612 in QTreeWidget::itemExpanded(QTreeWidgetItem*) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #90x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
    #10 0x00007ffff76ecc92 in QTreeView::expanded(QModelIndex const&) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #11 0x00007ffff76f8903 in QTreeView::expand(QModelIndex const&) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #12 0x00007ffff7724e44 in QTreeWidget::expandItem(QTreeWidgetItem const*) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #13 0x000000000070a0cb in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
    #14 0x000000000070a4c7 in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
    #15 0x000000000070a83d in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
    #16 0x000000000070a83d in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
    #17 0x000000000070beb6 in CBMTreeView::ReBuildTree(int) ()
    #18 0x000000000051eaff in CChildFrame::GetPanelMgrEx (this=0x1a1c3b0)
    at ../../Readerlite/ReaderLite/src/childframe.cpp:91
    #19 0x00000000005000c1 in CReader_DocViewEx::InitViewData (this=0x194ce60)
    at ../../Readerlite/ReaderLite/src/frd_docviewex.cpp:61
    #20 0x000000000048e691 in CPDF_OwnerFileTypeHandler::OpenContinueNormal (this=0x14c5470, pdoc=0x193a720, 
    filePath=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:99
    #21 0x000000000048f754 in CPDF_OwnerFileTypeHandler::DoOpen (this=0x14c5470, csFilterName=..., 
    wsPathName=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:216
    #22 0x000000000045d038 in CReader_AppEx::OwnerFileTypeHandlerDoOpen (this=0x14a47e0, csFDFFile=...)
    at ../../Readerlite/ReaderLite/src/frd_appex.cpp:941
    #23 0x000000000043caac in CMainWindow::OpenFile (this=0x14c4240, fileName=...)
    at ../../Readerlite/ReaderLite/src/mainwindow.cpp:434
    #24 0x0000000000439da9 in main (argc=2, argv=0x7fffffffe298) at ../../Readerlite/ReaderLite/src/main.cpp:301
    (gdb) x/10i $rip
    => 0xaab96c <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+94>:
    mov0x0(%r13,%rbp,8),%rcx
     0xaab971 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+99>:test %rcx,%rcx
     0xaab974 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+102>:
    jne0xaab983 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+117>
     0xaab976 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+104>: inc%rbp
     0xaab979 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+107>: movzbl 0xe(%rbx),%eax
     0xaab97d <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+111>: cmp%ebp,%eax
     0xaab97f <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+113>:
    jg 0xaab96c <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+94>
     0xaab981 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+115>:
    jmp0xaab99f <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+145>
     0xaab983 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+117>: mov0xc(%rsp),%esi
     0xaab987 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+121>: mov%r15,%r9
    (gdb) info reg
    rax0x7c 124
    rbx0x1a6613027681072
    rcx0xe1a704fcae02ca58 -2186773610767398312
    rdx0x7fffffffceec 140737488342764
    rsi0x2f 47
    rdi0x1a6613027681072
    rbp0x00x0
    rsp0x7fffffffce90 0x7fffffffce90
    r8 0xab0f92 11210642
    r9 0x6a83f4ca 1787032778
    r100xfd 253
    r110x00
    r120x7fffffffceec 140737488342764
    r130xe1a704fcae02ca58 -2186773610767398312
    r140xab0f92 11210642
    r150x6a83f4ca 1787032778
    rip0xaab96c 0xaab96c <CFX_BaseSegmentedArray::IterateIndex(int, int&, void**, int (*)(void*, void*), void*) const+94>
    eflags 0x10202[ IF RF ]
    cs 0x33 51
    ss 0x2b 43
    ds 0x00
    es 0x00
    fs 0x00
    gs 0x00
    --- cut ---
    
    Attached are three proof of concept PDF files.
    
    There is another crash likely related to this issue:
    
    --- cut ---
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000000ab0f94 in _CMapLookupCallback(void*, void*) ()
    (gdb) where
    #00x0000000000ab0f94 in _CMapLookupCallback(void*, void*) ()
    #10x0000000000aab8e4 in CFX_BaseSegmentedArray::IterateSegment(unsigned char const*, int, int (*)(void*, void*), void*) const ()
    #20x0000000000aab9dc in CFX_BaseSegmentedArray::Iterate(int (*)(void*, void*), void*) const ()
    #30x0000000000ab1a99 in CFX_CMapByteStringToPtr::Lookup(CFX_ByteStringC const&, void*&) const ()
    #40x00000000007db5df in CPDF_Dictionary::KeyExist(CFX_ByteStringC const&) const ()
    #50x000000000070e6a6 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
    #60x000000000070e6e3 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
    #70x000000000070f986 in CBMTreeCtrl::on_ItemExpanded(QTreeWidgetItem*) ()
    #80x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
    #90x00007ffff7722612 in QTreeWidget::itemExpanded(QTreeWidgetItem*) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #10 0x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
    #11 0x00007ffff76ecc92 in QTreeView::expanded(QModelIndex const&) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #12 0x00007ffff76f8903 in QTreeView::expand(QModelIndex const&) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #13 0x00007ffff7724e44 in QTreeWidget::expandItem(QTreeWidgetItem const*) ()
     from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
    #14 0x000000000070a0cb in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
    #15 0x000000000070a4c7 in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
    #16 0x000000000070beb6 in CBMTreeView::ReBuildTree(int) ()
    #17 0x000000000051eaff in CChildFrame::GetPanelMgrEx (this=0x196cf90)
    at ../../Readerlite/ReaderLite/src/childframe.cpp:91
    x#18 0x00000000005000c1 in CReader_DocViewEx::InitViewData (this=0x191dce0)
    at ../../Readerlite/ReaderLite/src/frd_docviewex.cpp:61
    #19 0x000000000048e691 in CPDF_OwnerFileTypeHandler::OpenContinueNormal (this=0x1468c50, pdoc=0x19194b0, 
    filePath=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:99
    /#20 0x000000000048f754 in CPDF_OwnerFileTypeHandler::DoOpen (this=0x1468c50, csFilterName=..., 
    wsPathName=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:216
    #21 0x000000000045d038 in CReader_AppEx::OwnerFileTypeHandlerDoOpen (this=0x144a920, csFDFFile=...)
    at ../../Readerlite/ReaderLite/src/frd_appex.cpp:941
    1#22 0x000000000043caac in CMainWindow::OpenFile (this=0x1468760, fileName=...)
    at ../../Readerlite/ReaderLite/src/mainwindow.cpp:434
    #23 0x0000000000439da9 in main (argc=2, argv=0x7fffffffe288) at ../../Readerlite/ReaderLite/src/main.cpp:301
    (gdb) x/10i $rip
    => 0xab0f94 <_Z19_CMapLookupCallbackPvS_+2>:cmp%edi,(%rsi)
     0xab0f96 <_Z19_CMapLookupCallbackPvS_+4>:jne0xab0fa1 <_Z19_CMapLookupCallbackPvS_+15>
     0xab0f98 <_Z19_CMapLookupCallbackPvS_+6>:xor%eax,%eax
     0xab0f9a <_Z19_CMapLookupCallbackPvS_+8>:cmpb $0xfe,0x4(%rsi)
     0xab0f9e <_Z19_CMapLookupCallbackPvS_+12>: setne%al
     0xab0fa1 <_Z19_CMapLookupCallbackPvS_+15>: xor$0x1,%eax
     0xab0fa4 <_Z19_CMapLookupCallbackPvS_+18>: retq 
     0xab0fa5 <_CompareDWord>:mov(%rdi),%eax
     0xab0fa7 <_CompareDWord+2>:sub(%rsi),%eax
     0xab0fa9 <_CompareDWord+4>:retq 
    (gdb) info reg $rsi
    rsi0x71 113
    --- cut ---
    
    Attached are three further files which reproduce the crash (note that MALLOC_CHECK_=3 might be necessary).
    
    
    Proof of Concept:
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39944.zip