Advertisement
darienhuss

Python malware extraction for 2018-07-05 HWP ROKRAT dropper

Jul 5th, 2018
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.80 KB | None | 0 0
  1. #extract malware from: 9e6ff58202f6c1bd2381e8209231efd0ef6855db59db975fb5b75041706ed104
  2. import re
  3. import sys
  4. import zlib
  5. import struct
  6. import hashlib
  7. import oledump
  8. import olefile
  9. import binascii
  10. import cStringIO
  11.  
  12. from hexdump import hexdump
  13. def md5(content):
  14.     return hashlib.md5(content).hexdigest()
  15.  
  16. def sha256(content):
  17.     return hashlib.sha256(content).hexdigest()
  18.  
  19. def writefile(filename,data):
  20.     with open(filename, 'wb') as f:
  21.         f.write(data)
  22.  
  23. def extract_payload(filename,postscript):
  24.    
  25.     if re.search(' corpqe\. ',postscript):
  26.         print '[+] Found CVE-2017-8291 (reversed), attempting extraction...'
  27.         if re.search('adobeprint token 1 pop pop exch pop exec \x0a',postscript):
  28.             print '[+] Found PS prior to encoded shellcode and payload, extracting...'
  29.             enc_shellcode_payload = re.search('adobeprint token 1 pop pop exch pop exec \x0a(.+)$',postscript, re.DOTALL).group(1)
  30.             #simple size check
  31.             if len(enc_shellcode_payload) > 100:
  32.                 key = ord(enc_shellcode_payload[0])
  33.                 print '[+] XOR key for encoded shellcode and payload: 0x%02X' % key
  34.                 enc_shellcode_payload = enc_shellcode_payload[1:]
  35.                 dec_shellcode_payload = ''
  36.                 for c in enc_shellcode_payload:
  37.                     dec_shellcode_payload += chr(ord(c)^key)
  38.                 dec_shellcode_payload = bytes(dec_shellcode_payload)
  39.                 if re.search('\\x8b\\x04\\x24\\xc3\\xe8',dec_shellcode_payload, re.S):
  40.                     print '[+] Found expected opcode bytes before encoded payload, extracting and decoding payload...'
  41.                     payload_re = re.compile('\\x8b\\x04\\x24\\xc3\\xe8.{4}\\xc3(.{4})(.{4})')
  42.                     payload_size = struct.unpack('<I',payload_re.search(dec_shellcode_payload).group(1))[0]
  43.                     print '[+] Payload size: %i' % payload_size
  44.                     key_payload = payload_re.search(dec_shellcode_payload).group(2)
  45.                     print '[+] Payload 4-byte XOR key: 0x%02X%02X%02X%02X' % (ord(key_payload[0]),ord(key_payload[1]),ord(key_payload[2]),ord(key_payload[3]))
  46.                     decoded = ''
  47.                     payload_pos = payload_re.search(dec_shellcode_payload).span(2)[1]
  48.                     encoded_payload = dec_shellcode_payload[payload_pos:payload_pos+payload_size]
  49.                     for i in range(len(encoded_payload)):
  50.                         decoded += chr(ord(encoded_payload[i])^ord(key_payload[i%4]))
  51.                 else:
  52.                     print '[!] Did not find the expected opcode bytes before encoded payload after decoding, exiting...'
  53.                     sys.exit()
  54.         else:
  55.             print '[!] Did not find PS before encoded payload, exiting...'
  56.             sys.exit()
  57.  
  58.  
  59.     else:
  60.         print '[!] Did not find expected reversed ".eqproc", exiting...'
  61.         sys.exit()
  62.  
  63.     md5_decoded = md5(decoded)
  64.     sha256_decoded = sha256(decoded)
  65.     decoded_filename = sha256_decoded
  66.  
  67.     print '[+] Decoded payload hashes:'
  68.     print '%s' % md5_decoded
  69.     print '%s' % sha256_decoded
  70.     print '[+] Writing decoded file to: %s\n' % decoded_filename
  71.     with open(decoded_filename, 'wb') as f:
  72.         f.write(decoded)
  73.  
  74. def main():
  75.     #code taken from Didier Stevens oledump script
  76.     #https://raw.githubusercontent.com/DidierStevens/DidierStevensSuite/master/oledump.py
  77.     filename = sys.argv[1]
  78.     oStringIO = cStringIO.StringIO(open(filename, 'rb').read())
  79.     magic = oStringIO.read(6)
  80.     oStringIO.seek(0)
  81.     if magic[0:4] != oledump.OLEFILE_MAGIC:
  82.         print '[!] This only supports OLE, exiting...'
  83.         sys.exit()
  84.     ole = olefile.OleFileIO(oStringIO)
  85.     for orphan, fname, entry_type, stream in oledump.OLEGetStreams(ole):
  86.         if fname[0] == 'BinData':
  87.             if re.search('BIN00\d{2}\.[Ee]?[Pp][Ss]',fname[1]):
  88.                 scriptname = fname[1]
  89.                 if '.eps' in scriptname:
  90.                     print '[+] Found EPS file: %s' % scriptname
  91.                 elif '.ps' in scriptname:
  92.                     print '[+] Found PS file: %s' % scriptname
  93.                 try:
  94.                     decompressed = zlib.decompress(stream, -15)
  95.                 except Exception, e:
  96.                     print '[!] Problem decompressing zlib stream, error:'
  97.                     print e
  98.                 extract_payload(filename,decompressed) 
  99.  
  100. if __name__ == '__main__':
  101.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement