예제 #1
0
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'])))
예제 #2
0
    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
예제 #3
0
 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
예제 #4
0
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
예제 #5
0
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))
예제 #6
0
 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)
예제 #7
0
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))