new_contents: """
  unpacks and looks for the url from guloaders wrapped in VB
  By: Jason Reaves
  Ref: https://www.proofpoint.com/us/threat-insight/post/guloader-popular-new-vb6-downloader-abuses-cloud-services
  """
  
  import pefile
  import sys
  import struct
  import yara
  
  rule_source = '''
  rule guloader
  {
      meta:
          author = "jreaves"
          description = "Guloader wrapper"
      strings:
          $snippet1 = {81 cf ?? ?? 40 00 85}
      condition:
          ($snippet1)
  }
  '''
  def yara_scan(raw_data, rule_name):
      addresses = {}
      yara_rules = yara.compile(source=rule_source)
      matches = yara_rules.match(data=raw_data)
      for match in matches:
          if match.rule == 'guloader':
              for item in match.strings:
                  if item[1] == rule_name:
                      addresses[item[1]] = item[0]
      return addresses
  
  def brute_it(data):
  	needle = struct.unpack('<I', '\x81\xec\x00\x02')[0]
  	for i in range(len(data)):
  		key = data[i+10:i+10+4]
  		key = key[2:] + key[:2]
  		key = struct.unpack('<I', key)[0]
  		if key ^ struct.unpack_from('<I', data[i:])[0] == needle:
  			return(data[i:])
  	return None
  
  
  if __name__ == "__main__":
  	data = open(sys.argv[1], 'rb').read()
  	pe = pefile.PE(data=data)
  	base = pe.OPTIONAL_HEADER.ImageBase
  	mapped = pe.get_memory_mapped_image()
  	oep = pe.OPTIONAL_HEADER.AddressOfEntryPoint
  	snippet = yara_scan(data, '$snippet1')
  	if snippet:
  		offset = int(snippet['$snippet1'])
  		mem_addr = struct.unpack_from('<I', data[offset+2:])[0]
  		mem_addr -= base
  		data = mapped[mem_addr:]
  	else:
  		data = brute_it(data)
  	if data != None:
  		key = data[10:10+4]
  		key = bytearray(key)
  		key = key[2:]+key[:2]
  		blob = bytearray(data)
  		for i in range(len(blob)):
  			blob[i] ^= key[i%len(key)]
  		if 'http' in blob:
  			off = blob.find('http')
  			print(blob[off:].split('\x00')[0])
  
  		
  
  
  
  
subject: Add guloader unpacker