def run_extractor(memory_instance, malware_sample, machine_instance=None): golden_image = pslist.load_golden_image(machine_instance) new_pslist = pslist.get_new_pslist(memory_instance) new_processes = [] for proc in new_pslist: new_proc = True for proc_gi in golden_image: if proc['PID'] == proc_gi['PID']: new_proc = False break # TODO! Local patch!! Remove on production!! if proc['Name'] == 'wmiprvse.exe': new_proc = False break if new_proc: logging.info('Identified a new process: {} - {}'.format(proc['PID'], proc['Name'])) new_processes.append(proc) workdir = os.path.dirname(os.path.realpath(malware_sample.file_path)) db_connection = DataBaseConnection() for procdata in new_processes: output = execute_volatility_command(memory_instance, 'procdump', extra_flags='-p {} -D {}/'.format(procdata['PID'], workdir), has_json_output=False) # Rename the file, to contain process name src = workdir + "/executable." + str(procdata['PID']) + ".exe" if os.path.isfile(src): target_dump_path = workdir + "/" + procdata['Name'] + "." + str(procdata['PID']) + "._exe" os.rename(src, target_dump_path) current_dump = SampleDump(target_dump_path) current_dump.sha256 = calc_sha256(target_dump_path) current_dump.md5 = calc_md5(target_dump_path) current_dump.ephash = calc_ephash(target_dump_path) current_dump.imphash = calc_imphash(target_dump_path) current_dump.process_name = procdata['Name'] current_dump.source = 'procdump' current_dump.parent_sample_id = malware_sample.id db_connection.add_dump(current_dump) # Load post processing modules here, if needed with open(target_dump_path + '.strings.json', 'w') as strings_output_file: strings_output_file.write(json.dumps(get_strings(current_dump), indent=4)) with open(target_dump_path + '.static_analysis.json', 'w') as strings_output_file: strings_output_file.write(json.dumps(static_analysis(current_dump), indent=4)) with open(target_dump_path + '.yara.json', 'w') as yara_output_file: yara_output_file.write(json.dumps(scan_with_yara(current_dump), indent=4)) else: logging.info('Could not dump process {} (PID: {})'.format(procdata['Name'], str(procdata['PID'])))
def get_waiting_sample_queue(self): all_samples = [] db_connection = DataBaseConnection() db_session = sessionmaker(bind=db_connection.engine) session = db_session() for instance in session.query(db_connection.samplesTable).filter( db_connection.samplesTable.c.status == 'waiting').all(): sample_entry = MalwareSample(instance.binary_path) sample_entry.sha256 = calc_sha256(instance.binary_path) sample_entry.get_sample_data() self.enqueue(sample_entry) session.close() return
def get_sample_data(self): if self.file_path.startswith(os.path.abspath(STORE_PATH) + '/'): logging.info( 'Sample is already in store, going to retrieve hashes from DB') db_connection = DataBaseConnection() sample = db_connection.sample_exists(self) self.id = sample[0] self.timestamp = sample[1] self.sha256 = sample[2] self.ephash = sample[3] self.imphash = sample[4] self.status = sample[5] self.md5 = sample[6] else: self.md5 = calc_md5(self.file_path) self.sha1 = calc_sha1(self.file_path) self.sha256 = calc_sha256(self.file_path) self.ephash = calc_ephash(self.file_path) self.imphash = calc_imphash(self.file_path) return
def static_analysis(sample_dump_instance): try: pe = pefile.PE(sample_dump_instance.binary_path) report = dict() report['imports'] = get_imports(pe) report['exports'] = get_exports(pe) report['general'] = { 'md5': calc_md5(sample_dump_instance.binary_path), 'sha256': calc_sha256(sample_dump_instance.binary_path), 'imphash': calc_imphash(sample_dump_instance.binary_path) } report['sections'] = get_section_data(pe) report['resources'] = get_resource_data(pe) return report except PEFormatError as exception: logging.error('Could not load PE file: {}'.format(exception)) return None except AttributeError as exception: logging.error('Could not load PE file: {}'.format(exception)) return None
def run_extractor(memory_instance, malware_sample,machine_instance=None): pslist_new_data = pslist.get_new_pslist(memory_instance) target_dump_dir = os.path.join(get_workdir_path(malware_sample), 'injected') os.mkdir(target_dump_dir) output = execute_volatility_command(memory_instance, 'malfind', extra_flags='-D {}/'.format(target_dump_dir), has_json_output=False) db_connection = DataBaseConnection() # Find malfind injections that are binaries, and rename them for single_dump in os.scandir(target_dump_dir): splitted_line = re.split('\.', single_dump.path.rstrip('\n')) logging.info('offset: {}, Imagebase: {}'.format(splitted_line[1], splitted_line[2])) offset = splitted_line[1] imagebase = splitted_line[2] # Verify if it is PE or not try: pe = pefile.PE(single_dump.path) isPE = True except PEFormatError: isPE = False if isPE: db_connection.add_tag("Injects_Code", malware_sample) logging.info('[*] Processing {}'.format(single_dump.path)) logging.info('offset: %s, Imagebase: %s'.format(offset, imagebase)) logging.info('Altering image base: {} => {}'.format(pe.OPTIONAL_HEADER.ImageBase, imagebase)) fixed_pe = fix_pe_from_memory(pe, imagebase=imagebase) # Get original process name process_name = "unknown" for proc_gi in pslist_new_data: if str(hex(proc_gi['Offset(V)'])) == offset: logging.info("Found process name: {}".format(proc_gi['Name'])) process_name = proc_gi['Name'] pid = str(proc_gi['PID']) break outputpath = os.path.join(target_dump_dir, process_name + '.' + offset + '.' + imagebase + '.fixed_bin') fixed_pe.write(filename=outputpath) pe.close() if process_name != 'unknown': # Generate impscan IDC output = execute_volatility_command(memory_instance, 'impscan', extra_flags='-b {} -p {} --output=idc'.format(imagebase, pid), has_json_output=False) # Write IDC data to file with open(outputpath + '.idc', 'w') as idc: idc.write('#include <idc.idc>\n') idc.write('static main(void) {{\n') idc.write(output) idc.write('Exit(0);}}') current_dump = SampleDump(outputpath) current_dump.parent_sample_id = malware_sample.id current_dump.sha256 = calc_sha256(outputpath) current_dump.md5 = calc_md5(outputpath) current_dump.process_name = process_name current_dump.source = 'injected_code' # Calc imphash, or make the parameter = fail current_dump.ephash = calc_ephash(outputpath) # Calc EPhash, or make the parameter = fail current_dump.imphash = calc_imphash(outputpath) db_connection.add_dump(current_dump) # Load post processing modules here, if needed with open(outputpath + '.strings.json', 'w') as strings_output_file: strings_output_file.write(json.dumps(get_strings(current_dump, imagebase=imagebase), indent=4)) with open(outputpath + '.static_analysis.json', 'w') as static_analysis_output_file: static_analysis_output_file.write(json.dumps(static_analysis(current_dump), indent=4)) with open(outputpath + '.yara.json', 'w') as yara_output_file: yara_output_file.write(json.dumps(scan_with_yara(current_dump), indent=4)) with open(outputpath + '.ysa.json', 'w') as yara_semantic_output_file: yara_semantic_output_file.write(json.dumps(semantically_analyze(current_dump), indent=4))
def calculate_hashes(self): self.md5 = calc_sha256(self.binary_path) self.sha256 = calc_sha256(self.binary_path) self.ephash = calc_ephash(self.binary_path) self.imphash = calc_imphash(self.binary_path)
def run_extractor(memory_instance, malware_sample,machine_instance=None): if machine_instance is None: return None # Whitelist of modules by name, not optimal at all... mod_white_list = ['TDTCP.SYS', 'RDPWD.SYS', 'kmixer.sys', 'Bthidbus.sys', 'rdpdr.sys', 'tdtcp.sys', 'tssecsrv.sys'] # Get golden image data: with open(os.path.join(VOLATILITYBOT_HOME, 'GoldenImage', machine_instance.machine_name, 'modscan.json')) as data_file: modscan_golden_image = json.load(data_file) modscan_run = execute_volatility_command(memory_instance, 'modscan') db_connection = DataBaseConnection() new_modules = [] for mod in modscan_run: new_mod = True for mod_gi in modscan_golden_image: if mod['File'] == mod_gi['File']: if mod['Size'] == mod_gi['Size']: new_mod = False for wl_mod in mod_white_list: # print '[DEBUG] modscan %s : %s' % (mod['filename'],wl_mod) if (mod['Name'] == wl_mod): new_mod = False if new_mod: logging.info('Identified a new module: {} - {}'.format(mod['File'], mod['Size'])) new_modules.append(mod) output = execute_volatility_command(memory_instance, 'moddump', extra_flags='-b {} -D {}/'.format(mod['Base'], get_workdir_path(malware_sample)), has_json_output=False) base = mod['Base'] src = os.path.join(get_workdir_path(malware_sample), "driver." + base[2:] + ".sys") dest = os.path.join(get_workdir_path(malware_sample), mod['Name'] + '.' + base[2:] + '.sys') try: os.rename(src, dest) except Exception as e: logging.error('Could not rename driver, leaving it as it is... ({})'.format(e) ) dest = src current_dump = SampleDump(dest) current_dump.parent_sample_id = malware_sample.id current_dump.sha256 = calc_sha256(dest) current_dump.md5 = calc_md5(dest) current_dump.process_name = mod['Name'] current_dump.source = 'KMD' current_dump.ephash = calc_ephash(dest) current_dump.imphash = calc_imphash(dest) db_connection.add_dump(current_dump) with open(dest + '.strings.json', 'w') as strings_output_file: strings_output_file.write(json.dumps(get_strings(current_dump), indent=4)) with open(dest + '.yara.json', 'w') as yara_output_file: yara_output_file.write(json.dumps(scan_with_yara(current_dump), indent=4))