Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #extract malware from: 6f1bddb3aa221635adfd8b1c465da64ab436648e3c14e44ccd118e96af50e5d7
- import re
- import sys
- import zlib
- import struct
- import hashlib
- import oledump
- import olefile
- import binascii
- import cStringIO
- from Crypto.Cipher import AES
- def md5(content):
- return hashlib.md5(content).hexdigest()
- def sha256(content):
- return hashlib.sha256(content).hexdigest()
- def writefile(filename,data):
- with open(filename, 'wb') as f:
- f.write(data)
- def aes_decrypt(encr,key,iv):
- cipher = AES.new(key, AES.MODE_CBC, iv)
- return cipher.decrypt(encr)
- def extract_payload(filename,postscript):
- if re.search('/FontSize <[A-F0-9]{8}>',postscript) and re.search(' def <[a-f0-9]{100,}>',postscript):
- print '[+] Found 4-byte XOR encoded PostScript, continuing...'
- key = re.search('/FontSize <([A-F0-9]{8})>',postscript).group(1).decode('hex')
- postscript_encoded = re.search(' def <([a-f0-9]{100,})>',postscript).group(1).decode('hex')
- postscript_decoded = ''
- for i in range(len(postscript_encoded)):
- postscript_decoded += chr(ord(postscript_encoded[i]) ^ ord(key[i%4]))
- if re.search('/shellcode <[a-f0-9]{100,}>',postscript_decoded):
- print '[+] Found hex-encoded shellcode in decoded PostScript, searching for AES key/IV...'
- shellcode = re.search('/shellcode <([a-f0-9]{100,})>',postscript_decoded).group(1).decode('hex')
- if re.search('(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4})).{6,10}\\xAA\\xC5\\xE2\\x5D.{6,12}\\xEE\\x95\\xB6\\x50.{6,12}\\xAE\\x87\\x92\\x3F',shellcode):
- print '[+] Found expected hashed WinAPIs trailing the AES key/IV, searching for key/IV'
- key_iv_segments = re.search('(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4}))(?:\\xC7\\x45.(.{4})).{6,10}\\xAA\\xC5\\xE2\\x5D.{6,12}\\xEE\\x95\\xB6\\x50.{6,12}\\xAE\\x87\\x92\\x3F',shellcode, re.S).groups()
- aes_key = ''
- aes_iv = ''
- for i in range(4):
- aes_key += key_iv_segments[i]
- for i in range(4,8):
- aes_iv += key_iv_segments[i]
- return aes_key,aes_iv
- else:
- print '[!] Did not find the expected hashed WinAPIs trailing the AES key/IV, try searching for bytes: C745E46578706C or C745B068707377 to find the function with the AES key/IV'
- else:
- print '[!] Did not find expected hex-encoded shellcode, exiting...'
- sys.exit()
- else:
- print '[!] Did not find expected 4-byte XOR PostScript, exiting...'
- sys.exit()
- md5_decoded = md5(decoded)
- sha256_decoded = sha256(decoded)
- decoded_filename = sha256_decoded
- print '[+] Decoded payload hashes:'
- print '%s' % md5_decoded
- print '%s' % sha256_decoded
- print '[+] Writing decoded file to: %s\n' % decoded_filename
- with open(decoded_filename, 'wb') as f:
- f.write(decoded)
- def main():
- #code taken from Didier Stevens oledump script
- #https://raw.githubusercontent.com/DidierStevens/DidierStevensSuite/master/oledump.py
- filename = sys.argv[1]
- oStringIO = cStringIO.StringIO(open(filename, 'rb').read())
- magic = oStringIO.read(6)
- oStringIO.seek(0)
- if magic[0:4] != oledump.OLEFILE_MAGIC:
- print '[!] This only supports OLE, exiting...'
- sys.exit()
- ole = olefile.OleFileIO(oStringIO)
- for orphan, fname, entry_type, stream in oledump.OLEGetStreams(ole):
- if fname[0] == 'BinData':
- if re.search('BIN00\d{2}\.[Ee]?[Pp][Ss]',fname[1]):
- scriptname = fname[1]
- if '.eps' in scriptname:
- print '[+] Found EPS file: %s' % scriptname
- elif '.ps' in scriptname:
- print '[+] Found PS file: %s' % scriptname
- try:
- decompressed = zlib.decompress(stream, -15)
- except Exception, e:
- print '[!] Problem decompressing zlib stream, error:'
- print e
- sys.exit()
- aes_key, aes_iv = extract_payload(filename,decompressed)
- print '[+] Found AES key: %s' % "".join("{:02x}".format(c) for c in bytearray(aes_key))
- print '[+] Found AES IV: %s' % "".join("{:02x}".format(c) for c in bytearray(aes_iv))
- if re.search('BIN00\d{2}\.[bB][mM][pP]',fname[1]):
- print '[+] Found BMP'
- stego_bmp = zlib.decompress(stream, -15)
- if re.search('F0und3g9',stego_bmp):
- print '[+] Found expected magic bytes (F0und3g9) prior to encrypted implants, extracting payloads now'
- x86_size_loc = re.search('F0und3g9',stego_bmp).span()[1]
- x86_size = struct.unpack('<I',stego_bmp[x86_size_loc:x86_size_loc+4])[0]
- x86_loc = x86_size_loc + 4
- x86_encrypted = stego_bmp[x86_loc:x86_loc+x86_size]
- x86_decrypted = aes_decrypt(x86_encrypted,aes_key,aes_iv)
- md5_x86 = md5(x86_decrypted)
- sha256_x86 = sha256(x86_decrypted)
- x64_size_loc = x86_loc+x86_size
- x64_size = struct.unpack('<I',stego_bmp[x64_size_loc:x64_size_loc+4])[0]
- x64_loc = x64_size_loc+4
- x64_encrypted = stego_bmp[x64_loc:x64_loc+x64_size]
- x64_decrypted = aes_decrypt(x64_encrypted,aes_key,aes_iv)
- md5_x64 = md5(x64_decrypted)
- sha256_x64 = sha256(x64_decrypted)
- print '[+] Decrypted file info:'
- print 'x86.bin|%s' % md5_x86
- print 'x86.bin|%s' % sha256_x86
- print 'x64.bin|%s' % md5_x64
- print 'x64.bin|%s\n' % sha256_x64
- print '[+] Writing x86.bin to: %s' % sha256_x86
- with open(sha256_x86, 'wb') as f:
- f.write(x86_decrypted)
- print '[+] Writing x64.bin to: %s' % sha256_x64
- with open(sha256_x64, 'wb') as f:
- f.write(x64_decrypted)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement