def main(): usage = "usage %prog <option> PE-file" parserInst = OptionParser(usage=usage, version="%prog 1.0") parser = prepareOptions(parserInst) (options, args) = parser.parse_args() if len(args) != 1: parser.error( "incorrect number of arguments: no PE file was specified.") if options.fast_load: pe = pype32.PE(args[0], fastLoad=True) else: pe = pype32.PE(args[0]) if options.show_headers: showDosHeaderData(pe) print "\n" showNtHeadersData(pe) print "\n" showFileHeaderData(pe) print "\n" showOptionalHeaderData(pe) print "\n" elif options.show_directories: showDataDirectoriesData(pe) elif options.show_section_headers: showSectionsHeaders(pe) elif options.show_signature: if len(pe.signature): print "--> Digital signature detected. Length: %x" % len( pe.signature) print "--> Signature (first 0x10 bytes): %r" % pe.signature[:0x10] elif options.show_overlay: if len(pe.overlay): print "--> Overlay detected. Length: %x" % len(pe.overlay) elif options.show_imports: showImports(pe) elif options.show_exports: showExports(pe) elif options.section_data: pe.addSection(section_data) elif options.multi: if len(pe.sections): try: index = int(options.multi[0]) except ValueError: raise "First parameter must be an integer!." pe.extendSection(options.multi[0], options.multi[1]) else: print "PE has no section to extend!." else: parser.print_help()
def config(data): pe = pype32.PE(data=data) string_list = get_strings(pe, 2) key, salt = 'HawkEyeKeylogger', '3000390039007500370038003700390037003800370038003600'.decode( 'hex') config_dict = config_1(key, salt, string_list) return config_dict
def config(raw_data): try: pe = pype32.PE(data=raw_data) string_list = get_strings(pe, 2) vers = get_version(string_list) if vers == "v12": config_dict = config_12(string_list) elif vers == "v13": key, salt = "PredatorLogger", "3000390039007500370038003700390037003800370038003600".decode( "hex") config_dict = config_13(key, salt, string_list) elif vers == "v14": key, salt = "EncryptedCredentials", "3000390039007500370038003700390037003800370038003600".decode( "hex") config_dict = config_14(key, salt, string_list) else: return False # C2 Line is not a straight domain on this one. if config_dict: return config_dict else: return False except Exception as e: return False
def get_codedconfig(data): """ This gets the encoded config from a stub """ coded_config = None try: pe = pe = pype32.PE(data=data) m = pe.ntHeaders.optionalHeader.dataDirectory[14].info for i in m.directory.resources.info: if i['name'] == "Data.bin": coded_config = i["data"] except: pe = pefile.PE(data=data) for entry in pe.DIRECTORY_ENTRY_RESOURCE.entries: if str(entry.name) == "RC_DATA" or "RCData": new_dirs = entry.directory for res in new_dirs.entries: data_rva = res.directory.entries[ 0].data.struct.OffsetToData size = res.directory.entries[0].data.struct.Size data = pe.get_memory_mapped_image()[data_rva:data_rva + size] coded_config = data # Icons can get in the way. if coded_config.startswith('\x28\x00\x00'): break return coded_config
def config(raw_data): try: pe = pype32.PE(data=raw_data) string_list = get_strings(pe, 2) vers = get_version(string_list) if vers == 'v12': config_dict = config_12(string_list) elif vers == 'v13': key, salt = 'PredatorLogger', '3000390039007500370038003700390037003800370038003600'.decode( 'hex') config_dict = config_13(key, salt, string_list) elif vers == 'v14': key, salt = 'EncryptedCredentials', '3000390039007500370038003700390037003800370038003600'.decode( 'hex') config_dict = config_14(key, salt, string_list) else: return False # C2 Line is not a straight domain on this one. if config_dict: return config_dict else: return False except Exception as e: return False
def get_bot_information(self, file_data): results = {} pe = pype32.PE(data=file_data) string_list = GruntStager._get_strings(pe, 2) c2_url = string_list[1] results['c2_uri'] = c2_url return results
def run(data): pe = pype32.PE(data=data) print " [-] Collecting Strings" string_list = get_strings(pe, '#US') key, salt = 'HawkEyeKeylogger', '3000390039007500370038003700390037003800370038003600'.decode( 'hex') config_dict = config_1(key, salt, string_list) return config_dict
def config(raw_data): try: pe = pype32.PE(data=raw_data) string_list = get_strings(pe, 2) key, salt = 'HawkEyeKeylogger', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_1(key, salt, string_list) return config_dict except Exception as e: return False
def config(data): try: pe = pype32.PE(data=data) string_list = get_strings(pe, 2) config_dict = parse_config(string_list) return config_dict except Exception as e: self.log('error', e) return None
def get_bot_information(self, file_data): results = {} pe = pype32.PE(data=file_data) string_list = njRat._get_strings(pe, 2) config_dict = njRat._parse_config(string_list) if config_dict: domain = config_dict["Domain"] port = config_dict["Port"] results['c2_uri'] = "{0}:{1}".format(domain, port) results['version'] = config_dict["version"] return results
def config(raw_data): try: pe = pype32.PE(data=raw_data) string_list = get_strings(pe, 2) config_dict = parse_config(string_list) if config_dict: return config_dict else: return False except Exception as e: return False
def run(data): try: pe = pype32.PE(data=data) rawConfig = getStream(pe) # Get a list of strings stringList = parseStrings(rawConfig) #parse the string list dict = parseConfig(stringList) return dict except: return None
def run(data): try: pe = pype32.PE(data=data) string_list = get_strings(pe, 2) #print string_list #parse the string list config_dict = parse_config(string_list) return config_dict except Exception as e: print e return None
def run(data): pe = pype32.PE(data=data) print(" [-] Collecting Strings") string_list = get_strings(pe, 2) # identify the version if 'InvisibleSoft' in string_list: key, salt = 'InvisibleSoft', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_2(key, salt, string_list) else: key, salt = 'HawkEyeKeylogger', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_1(key, salt, string_list) return config_dict
def run(md5, rawData): rawconfig = rawData.split("abccba") if len(rawconfig) > 1: log.info("Running Abccba") conf = oldversions(rawconfig) else: log.info("Running pype32") pe = pype32.PE(data=rawData) rawConfig = getStream(pe) conf = parseConfig(rawConfig) if not conf: return None database.insertDomain(md5, [conf["Domain"]]) return conf
def extract_config(file_path): if not HAVE_PYPE32: return None data = open(file_path, "rb").read() try: pe = pype32.PE(data=data) rawConfig = getStream(pe) # Get a list of strings stringList = parseStrings(rawConfig) #parse the string list dict = parseConfig(stringList) return dict except: return None
def extract_net_resource(pe, folder): resources = [] pe = pype32.PE(folder + '/' + pe) m = pe.ntHeaders.optionalHeader.dataDirectory[14].info for i in m.directory.resources.info: data = pe.getDataAtRva(m.directory.resources.rva.value + i['offset'], i['size']) state = decode_manifest(data, folder) if state == False: with open(folder + '/' + i["name"], "wb") as f: f.write(data) return resources
def run(rawData): #try: rawconfig = rawData.split("abccba") if len(rawconfig) > 1: print "Running Abccba" dict = oldversions(rawconfig) else: print "Running pype32" pe = pype32.PE(data=rawData) rawConfig = getStream(pe) if rawConfig.startswith("bute"): # workaround for an error in pype32 will still work when fixed rawConfig = rawConfig[8:] dict = parseConfig(rawConfig) #except: #return None print dict
def config(data): pe = pype32.PE(data=data) string_list = get_strings(pe, 2) vers = get_version(string_list) if vers == 'v12': config_dict = config_12(string_list) elif vers == 'v13': key, salt = 'PredatorLogger', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_13(key, salt, string_list) elif vers == 'v14': key, salt = 'EncryptedCredentials', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_14(key, salt, string_list) else: return return config_dict
def run(data): pe = pype32.PE(data=data) print " [-] Collecting Strings" string_list = get_strings(pe, '#US') print " [+] Identify version" vers = get_version(string_list) if vers == 'v12': config_dict = config_12(string_list) elif vers == 'v13': key, salt = 'PredatorLogger', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_13(key, salt, string_list) elif vers == 'v14': key, salt = 'EncryptedCredentials', '3000390039007500370038003700390037003800370038003600'.decode('hex') config_dict = config_14(key, salt, string_list) else: return return config_dict
def get_bot_information(self, file_data): results = {} B64_REGEX = re.compile('[a-zA-Z0-9/+\=]{20,88}') C2_REGEX = re.compile('[a-z0-9\._\-]{1,100}:[0-9]{1,5}', re.IGNORECASE) pe = pype32.PE(data=file_data) string_list = VoidRAT._get_strings(pe, 2) cfg_strings = [] for i in range(0, len(string_list)): if len(string_list[i]) == 88 and B64_REGEX.match(string_list[i]): for j in range(0, 10): cfg_strings.append(string_list[i + j]) break ciphertext = str(cfg_strings[1]) encryptionkey = str(cfg_strings[8]) c2 = VoidRAT._void_decrypt(ciphertext, encryptionkey) if C2_REGEX.match(c2): results['c2_uri'] = c2 return results
def extract_config(raw_data): try: pe = pype32.PE(data=raw_data) # pe = pefile.PE(data=raw_data) string_list = get_strings(pe, 2) vers = get_version(string_list) if vers == "v12": config_dict = config_12(string_list) elif vers == "v13": key, salt = "PredatorLogger", unhexlify( "3000390039007500370038003700390037003800370038003600") config_dict = config_13(key, salt, string_list) elif vers == "v14": key, salt = "EncryptedCredentials", unhexlify( "3000390039007500370038003700390037003800370038003600") config_dict = config_14(key, salt, string_list) else: return False # C2 Line is not a straight domain on this one. return config_dict or False except Exception as e: print("PREDATORPAIN EXTRACTOR", e) return False
break return data print "+++ Unpacker for Venis ransomware +++\n" print "-- written by +NCR/CRC! [ReVeRsEr]" print "crackinglandia[at]gmail.com\n" if len(sys.argv) < 2: print "Usage: %s <filename>" % __file__ sys.exit(1) filename = sys.argv[1] print "[-] Processing %s" % filename p = pype32.PE(filename) print "[-] Getting .text section data..." text_section_code = get_section_data(p, ".text") print "[-] Done." func_name = "SizeofResource" print "[-] Searching %s function on the IMPORT_DIRECTORY..." % func_name func_addr = get_imp_function_address(p, func_name) if func_addr != 0: print "[-] %s found at 0x%x" % (func_name, func_addr) print "[-] Searching for XORED_DATA_OFFSET value..." XORED_DATA_OFFSET = get_xor_data_offset(text_section_code, func_addr) if XORED_DATA_OFFSET != -1: print "[-] XORED_DATA_OFFSET found: 0x%x" % XORED_DATA_OFFSET
def get_bot_information(self, file_data): results = {} B64_REGEX = re.compile('[a-zA-Z0-9/+\=]{20,88}') C2_REGEX = re.compile('[a-z0-9\._\-]{1,100}:[0-9]{1,5}', re.IGNORECASE) KEY_REGEX = re.compile('[a-zA-Z0-9]{32}') pe = pype32.PE(data=file_data) string_list = AsyncRAT._get_strings(pe, 2) # check for and extract strings from unencoded config if '(ext8,ext16,ex32) type $c7,$c8,$c9' in string_list: cfg_strings = [] for i in range(0, len(string_list)): if len(string_list[i]) == 88 and B64_REGEX.match( string_list[i]): for j in range(0, 10): cfg_strings.append(string_list[i + j]) break elif C2_REGEX.match(string_list[i + 1] + ':' + string_list[i]): c2 = str(string_list[i + 1] + ':' + string_list[i]) results['c2_uri'] = c2 return results ports_ciphertext = base64.b64decode(cfg_strings[0]) hosts_ciphertext = base64.b64decode(cfg_strings[1]) encryptionkey = base64.b64decode(cfg_strings[6]) # check for, decode, and extract strings from base64 encoded config elif 'KGV4dDgsZXh0MTYsZXgzMikgdHlwZSAkYzcsJGM4LCRjOQ==' in string_list: clear_strings = [] for a in string_list: try: clear_strings.append(base64.b64decode(a)) except: pass cfg_strings = [] for i in range(0, len(clear_strings)): if clear_strings[ i] == '{{ ProcessId = {0}, Name = {1}, ExecutablePath = {2} }}': for j in range(1, 8): cfg_strings.append(clear_strings[i + j]) break ports_ciphertext = cfg_strings[0] hosts_ciphertext = cfg_strings[1] for i in range(2, len(cfg_strings) - 1): if KEY_REGEX.match(cfg_strings[i]): encryptionkey = cfg_strings[i] break else: return results ports = AsyncRAT._async_decrypt(ports_ciphertext, encryptionkey) port_list = ports.split(',') hosts = AsyncRAT._async_decrypt(hosts_ciphertext, encryptionkey) host_list = hosts.split(',') if len(host_list[0]) > 1 or hosts[0] == ',': results['c2s'] = [] for h in host_list: for p in port_list: c2 = str("{0}:{1}".format(h, p)) if C2_REGEX.match(c2): results['c2s'].append({"c2_uri": c2}) return results
def config(data): pe = pype32.PE(data=data) string_list = get_strings(pe, 2) config_dict = parse_config(string_list) return config_dict
parser.add_argument("quasar_executable", help="the quasar executable file") parser.add_argument("version", choices=["apt10", "standard"], default="standard", help="the version of quasar to parse") options = parser.parse_args() quasar_file_path = os.path.abspath(options.quasar_executable) if not os.path.exists(quasar_file_path): print "File does not exist" sys.exit() choice = {"apt10": extract_config_apt10, "standard": extract_config_standard} config = choice[options.version](pype32.PE(quasar_file_path)) if options.version == "apt10": aes_mode = AES.MODE_CFB else: aes_mode = AES.MODE_CBC if not config: print "Configuration data not found" sys.exit() if "Key" not in config: print "Key used for configuration encryption not found!" sys.exit() derived_key = PBKDF2(config["Key"], salt, 50000)
def process(*args, **kwargs): plugin_args = kwargs["args"] store_plugin = kwargs["plugin_dir"] pi_directories = [ os.path.abspath(pidir) for pidir in plugin_args["peinfo_directories"] ] pi_directory_recursive = plugin_args["peinfo_recursion"] pi_skip = plugin_args["peinfo_skip"] if not pi_skip: #assemble file list for analysis file_list = [] for pidir in pi_directories: if pi_directory_recursive: logging.info("Looking recursively for files in directory %s" % pidir) for root, dirs, files in os.walk(pidir): if files is not None: for file in files: fabs = os.path.abspath(os.path.join(root, file)) hnd = open(fabs, "rb") if hnd.read(2) == "MZ": file_list.append( os.path.abspath(os.path.join(root, file))) else: logging.info("Looking for files in directory %s" % pidir) for file in os.listdir(pidir): file = os.path.abspath(os.path.join(pidir, file)) if os.path.isfile(file): hnd = open(file, "rb") if hnd.read(2) == "MZ": file_list.append(file) peinfo_list = [] if not pi_skip: logging.info("Identified %d files. Starting analysis now." % len(file_list)) #create peinfo_list for file in file_list: try: pe = pefile.PE(file) header_checksum = "0x%02x" % pe.OPTIONAL_HEADER.CheckSum calculated_checksum = "0x%02x" % pe.generate_checksum() except Exception as e: logging.error("Error analyzing checksum. Will set to -1: %s" % str(e)) header_checksum = -1 calculated_checksum = -1 try: pe32 = pype32.PE(file, fastLoad=True) overlay = "0x%x" % len(pe32.overlay) digital_signature_length = "0x%x" % len(pe32.signature) except Exception as e: logging.error( "Error analyzing overlay and digital signature. Will set to -1: %s" % str(e)) overlay = -1 digital_signature_length = -1 md5, sha1, sha256 = calculate_hashes(file) details = [ line.decode("ascii", 'ignore') + '\n' for line in pecheck(file) ] peinfo_list.append({ 'filepath': os.path.split(file)[0], 'filename': os.path.split(file)[1], 'filesize': os.path.getsize(file), 'header_checksum': header_checksum, 'calculated_checksum': calculated_checksum, 'overlay_size': overlay, 'signature_size': digital_signature_length, 'md5': md5, 'sha1': sha1, 'sha256': sha256, 'details': details }) if not pi_skip: save_results(store_plugin, peinfo_list) create_report(store_plugin) logging.info("Plugin analysis completed!")
def __init__(self, options): self.__options = options self.__binary = pype32.PE(self.__options.binary) print '[+] Parsing PE file completed.'