def tags(tag_action=False): # Set DB db = Database() # Search or Delete if request.method == 'GET': action = request.query.action value = request.query.value.strip() if value: if action == 'search': # This will search all projects # Get project list projects = project_list() # Add Main db to list. projects.append('../') # Search All projects p_list = [] results = {} for project in projects: __project__.open(project) # Init DB db = Database() #get results proj_results = [] rows = db.find(key='tag', value=value) for row in rows: if project == '../': project = 'Main' proj_results.append([row.name, row.sha256]) results[project] = proj_results p_list.append(project) # Return the search template return template('search.tpl', projects=p_list, results=results) else: return template('error.tpl', error="'{0}' Is not a valid tag action".format(action)) # Add / Delete if request.method == 'POST': file_hash = request.forms.get('sha256') project = request.forms.get('project') tag_name = request.forms.get('tag') if tag_action == 'add': if file_hash and project: tags = request.forms.get('tags') db.add_tags(file_hash, tags) if tag_action == 'del': if file_hash and tag_name: db.delete_tag(tag_name, file_hash) redirect('/file/{0}/{1}'.format(project, file_hash))
def _search_local_hashes(self, event, open_session=True): local = [] samples_count = 0 if isinstance(event, MISPEvent): misp_event = event elif event.get('Event') is None: self.log('error', event) return else: misp_event = MISPEvent() misp_event.load(event) if not hasattr(misp_event, 'id'): # The event doesn't exists upstream, breaking. return for a in misp_event.attributes: row = None if a.type == 'malware-sample': samples_count += 1 if a.type in ('md5', 'sha1', 'sha256'): row = Database().find(key=a.type, value=a.value) elif a.type in ('filename|md5', 'filename|sha1', 'filename|sha256'): row = Database().find(key=a.type.split('|')[1], value=a.value.split('|')[1]) elif a.type == 'malware-sample': row = Database().find(key='md5', value=a.value.split('|')[1]) if row: local.append(row[0]) self.log( 'info', 'Event {} contains {} samples.'.format(misp_event.id, samples_count)) if not open_session: return shas = set([l.sha256 for l in local]) if len(shas) == 1: __sessions__.new(get_sample_path(shas.pop()), MispEvent(misp_event, self.offline_mode)) elif len(shas) > 1: self.log('success', 'The following samples are in this viper instance:') __sessions__.new( misp_event=MispEvent(misp_event, self.offline_mode)) for s in shas: self.log('item', s) else: __sessions__.new( misp_event=MispEvent(misp_event, self.offline_mode)) self.log('info', 'No known (in Viper) samples in that event.')
def new(self, path): session = Session() total = len(self.sessions) session.id = total + 1 # Open a section on the given file. session.file = File(path) # Try to lookup the file in the database. If it is already present # we get file name and row = Database().find(key='sha256', value=session.file.sha256) if row: session.file.name = row[0].name session.file.tags = ', '.join(tag.to_dict()['tag'] for tag in row[0].tag) # Loop through all existing sessions and check whether there's another # session open on the same file and delete it. This is to avoid # duplicates in sessions. # NOTE: in the future we might want to remove this if sessions have # unique attributes (for example, an history just for each of them). for entry in self.sessions: if entry.file.sha256 == session.file.sha256: self.sessions.remove(entry) # Add new session to the list. self.sessions.append(session) # Mark the new session as the current one. self.current = session print_info("Session opened on {0}".format(path))
def peid(self): def get_signatures(): with file(os.path.join(VIPER_ROOT, 'data/peid/UserDB.TXT'), 'rt') as f: sig_data = f.read() signatures = peutils.SignatureDatabase(data=sig_data) return signatures def get_matches(pe, signatures): matches = signatures.match_all(pe, ep_only=True) return matches if not self.__check_session(): return signatures = get_signatures() peid_matches = get_matches(self.pe, signatures) if peid_matches: self.log('info', "PEiD Signatures:") for sig in peid_matches: if type(sig) is list: self.log('item', sig[0]) else: self.log('item', sig) else: self.log('info', "No PEiD signatures matched.") if self.args.scan and peid_matches: self.log('info', "Scanning the repository for matching samples...") db = Database() samples = db.find(key='all') matches = [] for sample in samples: if sample.sha256 == __sessions__.current.file.sha256: continue sample_path = get_sample_path(sample.sha256) if not os.path.exists(sample_path): continue try: cur_pe = pefile.PE(sample_path) cur_peid_matches = get_matches(cur_pe, signatures) except: continue if peid_matches == cur_peid_matches: matches.append([sample.name, sample.sha256]) self.log('info', "{0} relevant matches found".format(bold(len(matches)))) if len(matches) > 0: self.log('table', dict(header=['Name', 'SHA256'], rows=matches))
def logo(): print(""" _ (_) _ _ _ ____ _____ ____ | | | | | _ \| ___ |/ ___) \ V /| | |_| | ____| | \_/ |_| __/|_____)_| v{} |_| """.format(__version__)) db = Database() count = db.get_sample_count() try: db.find('all') except Exception: print_error("You need to update your Viper database. Run 'python update.py -d'") sys.exit() if __project__.name: name = __project__.name else: name = 'default' print(magenta("You have " + bold(count)) + magenta(" files in your " + bold(name)) + magenta(" repository"))
def __init__(self): # Open connection to the database. self.db = Database() # Map commands to their related functions. self.commands = dict( help=dict(obj=self.cmd_help, description="Show this help message"), open=dict(obj=self.cmd_open, description="Open a file"), close=dict(obj=self.cmd_close, description="Close the current session"), info=dict(obj=self.cmd_info, description="Show information on the opened file"), notes=dict( obj=self.cmd_notes, description="View, add and edit notes on the opened file"), clear=dict(obj=self.cmd_clear, description="Clear the console"), store=dict( obj=self.cmd_store, description="Store the opened file to the local repository"), delete=dict(obj=self.cmd_delete, description="Delete the opened file"), find=dict(obj=self.cmd_find, description="Find a file"), tags=dict(obj=self.cmd_tags, description="Modify tags of the opened file"), sessions=dict(obj=self.cmd_sessions, description="List or switch sessions"), projects=dict(obj=self.cmd_projects, description="List or switch existing projects"), export=dict( obj=self.cmd_export, description="Export the current session to file or zip"), )
def module_cmdline(project=None, cmd_line=None, file_hash=None): html = "" cmd = Commands() split_commands = cmd_line.split(';') for split_command in split_commands: split_command = split_command.strip() if not split_command: continue root, args = parse(split_command) try: if root in cmd.commands: cmd.commands[root]['obj'](*args) html += print_output(cmd.output) del (cmd.output[:]) elif root in __modules__: # if prev commands did not open a session open one on the current file if file_hash: __project__.open(project) path = get_sample_path(file_hash) __sessions__.new(path) module = __modules__[root]['obj']() module.set_commandline(args) module.run() html += print_output(module.output) if cfg.modules.store_output and __sessions__.is_set(): Database().add_analysis(file_hash, split_command, module.output) del (module.output[:]) else: html += '<p class="text-danger">{0} is not a valid command</p>'.format(cmd_line) except Exception: html += '<p class="text-danger">We were unable to complete the command {0}</p>'.format(cmd_line) __sessions__.close() return html
def parse_message(self, message_folder): db = Database() email_header = os.path.join(message_folder, 'InternetHeaders.txt') email_body = os.path.join(message_folder, 'Message.txt') envelope = headers = email_text = '' if os.path.exists(email_header): envelope, headers = self.email_headers(email_header) if os.path.exists(email_body): email_text = open(email_body, 'rb').read() tags = 'pst, {0}'.format(message_folder) if os.path.exists(os.path.join(message_folder, 'Attachments')): for filename in os.listdir( os.path.join(message_folder, 'Attachments')): if os.path.isfile( os.path.join(message_folder, 'Attachments', filename)): obj = File( os.path.join(message_folder, 'Attachments', filename)) sha256 = hashlib.sha256( open( os.path.join(message_folder, 'Attachments', filename), 'rb').read()).hexdigest() new_path = store_sample(obj) if new_path: # Add file to the database. db.add(obj=obj, tags=tags) # Add Email Details as a Note # To handle duplicates we use multiple notes headers_body = 'Envelope: \n{0}\nHeaders: \n{1}\n'.format( envelope, headers) db.add_note(sha256, 'Headers', headers_body) # Add a note with email body db.add_note(sha256, 'Email Body', string_clean(email_text))
def get_file(file_hash): key = '' if len(file_hash) == 32: key = 'md5' elif len(file_hash) == 64: key = 'sha256' else: response.code = 400 return jsonize({'message':'Invalid hash format (use md5 or sha256)'}) db = Database() rows = db.find(key=key, value=file_hash) if not rows: response.code = 404 return jsonize({'message':'File not found in the database'}) path = get_sample_path(rows[0].sha256) if not path: response.code = 404 return jsonize({'message':'File not found in the repository'}) response.content_length = os.path.getsize(path) response.content_type = 'application/octet-stream; charset=UTF-8' data = '' for chunk in File(path).get_chunks(): data += chunk return data
def pehash(self): if not HAVE_PEHASH: self.log( 'error', "PEhash is missing. Please copy PEhash to the modules directory of Viper" ) return current_pehash = None if __sessions__.is_set(): current_pehash = calculate_pehash(__sessions__.current.file.path) self.log('info', "PEhash: {0}".format(bold(current_pehash))) if self.args.all or self.args.cluster or self.args.scan: db = Database() samples = db.find(key='all') rows = [] for sample in samples: sample_path = get_sample_path(sample.sha256) pe_hash = calculate_pehash(sample_path) if pe_hash: rows.append((sample.name, sample.md5, pe_hash)) if self.args.all: self.log('info', "PEhash for all files:") header = ['Name', 'MD5', 'PEhash'] self.log('table', dict(header=header, rows=rows)) elif self.args.cluster: self.log('info', "Clustering files by PEhash...") cluster = {} for sample_name, sample_md5, pe_hash in rows: cluster.setdefault(pe_hash, []).append([sample_name, sample_md5]) for item in cluster.items(): if len(item[1]) > 1: self.log( 'info', "PEhash {0} was calculated on files:".format( bold(item[0]))) self.log('table', dict(header=['Name', 'MD5'], rows=item[1])) elif self.args.scan: if __sessions__.is_set() and current_pehash: self.log('info', "Finding matching samples...") matches = [] for row in rows: if row[1] == __sessions__.current.file.md5: continue if row[2] == current_pehash: matches.append([row[0], row[1]]) if matches: self.log('table', dict(header=['Name', 'MD5'], rows=matches)) else: self.log('info', "No matches found")
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return if __sessions__.is_set(): if not __sessions__.current.file.id: self.log( 'error', "The opened file does not have an ID, have you stored it yet?" ) return self.log( 'info', "Current name is: {}".format( bold(__sessions__.current.file.name))) new_name = input("New name: ") if not new_name: self.log('error', "File name can't be empty!") return Database().rename(__sessions__.current.file.id, new_name) self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path) else: self.log( 'error', "No open session. This command expects a file to be open.")
def run(self): super(Strings, self).run() if self.args is None: return if not (self.args.all or self.args.files or self.args.hosts or self.args.network or self.args.interesting): self.log('error', 'At least one of the parameters is required') self.usage() return if self.args.scan: db = Database() samples = db.find(key='all') for sample in samples: sample_path = get_sample_path(sample.sha256) strings = self.get_strings(File(sample_path)) self.process_strings(strings, sample.name) else: if not __sessions__.is_set(): self.log('error', "No open session") return if os.path.exists(__sessions__.current.file.path): strings = self.get_strings(__sessions__.current.file) self.process_strings(strings)
def run(self): super(Radiff2, self).run() if self.args is None: return if not __sessions__.is_set(): self.log('error', "No open session") return db = Database() samples = None if self.args.samples: samples = db.find(key='any', value=self.args.samples) if self.args.all: samples = db.find(key='all') if samples is None: self.log('error', "No samples found") return session_file = __sessions__.current.file.name for malware in samples: if malware.sha256 == __sessions__.current.file.sha256: continue sample = st.get_sample_path(malware.sha256) out = self.diff_files(__sessions__.current.file.path, sample) match, part, no_match, stat = self.process_output( out, self.args.nomatch) if self.args.verbose: self.print_result(match, part, no_match, session_file, malware.name) self.print_stat(stat, session_file, malware.name)
def run(self): super(Strings, self).run() if self.args is None: return if not (self.args.all or self.args.files or self.args.hosts or self.args.network or self.args.interesting or self.args.search_string): self.log('error', 'At least one of the parameters is required') self.usage() return if self.args.scan: db = Database() samples = db.find(key='all') for sample in samples: sample_path = get_sample_path(sample.sha256) strings = self.get_strings_base(sample_path, xor_key=self.args.xor, rabin_extract=self.args.rabin2) self.process_strings(strings, sample.name) else: if not __sessions__.is_set(): self.log('error', "No open session. This command expects a file to be open.") return if os.path.exists(__sessions__.current.file.path): strings = self.get_strings_base(__sessions__.current.file.path, xor_key=self.args.xor, rabin_extract=self.args.rabin2) self.process_strings(strings)
def autorun_module(file_hash): if not file_hash: return # We need an open session if not __sessions__.is_set(): # Open session __sessions__.new(get_sample_path(file_hash)) for cmd_line in cfg.autorun.commands.split(','): split_commands = cmd_line.split(';') for split_command in split_commands: split_command = split_command.strip() if not split_command: continue root, args = parse(split_command) try: if root in __modules__: module = __modules__[root]['obj']() module.set_commandline(args) module.run() print_info("Running Command {0}".format(split_command)) if cfg.modules.store_output and __sessions__.is_set(): Database().add_analysis(file_hash, split_command, module.output) if cfg.autorun.verbose: print_output(module.output) del (module.output[:]) else: print_error( '{0} is not a valid command. Please check your viper.conf file.' .format(cmd_line)) except: print_error( 'Viper was unable to complete the command {0}'.format( cmd_line)) return
def file_download(file_hash, project=False): if project in project_list(): __project__.open(project) else: __project__.open('../') project = 'Main' # Open the Database db = Database() # Open a session rows = db.find(key='sha256', value=file_hash) if not rows: return template( 'error.tpl', error="{0} Does not match any hash in the Database".format( file_hash)) path = get_sample_path(rows[0].sha256) if not path: return template('error.tpl', error="File not found on disk") response.content_length = os.path.getsize(path) response.content_type = 'application/octet-stream; charset=UTF-8' data = '' for chunk in File(path).get_chunks(): data += chunk return data
def add_file(file_path, name=None, tags=None, parent=None): obj = File(file_path) new_path = store_sample(obj, __project__) print(new_path) if not name: name = os.path.basename(file_path) # success = True if new_path: # Add file to the database. try: db = Database() db.add(obj=obj, name=name, tags=tags, parent_sha=parent) except Exception as e: log.error("Exception while adding sample to DB: {str(e)}") # Removing stored file since DB write failed remove_sample(new_path) return None # AutoRun Modules if cfg.autorun.enabled: autorun_module(obj.sha256) # Close the open session to keep the session table clean __sessions__.close() return obj.sha256 else: log.info("File already exists in database") return None
def logo(): print(""" _ (_) _ _ _ ____ _____ ____ | | | | | _ \| ___ |/ ___) \ V /| | |_| | ____| | \_/ |_| __/|_____)_| v1.3-dev |_| """) db = Database() count = db.get_sample_count() # Handle the New database format try: db.find('all', None) except: print_error( "You need to update your viper database. Run 'python update.py -d'" ) sys.exit() if __project__.name: name = __project__.name else: name = 'default' print( magenta("You have " + bold(count)) + magenta(" files in your " + bold(name) + magenta(" repository".format(bold(name))))) if cfg.autorun.enabled and len(cfg.autorun.commands) == 0: print_warning( "You have enabled autorun but not set any commands in viper.conf.")
def url_download(): url = request.forms.get('url') tags = request.forms.get('tag_list') tags = "url," + tags if request.forms.get("tor"): upload = network.download(url, tor=True) else: upload = network.download(url, tor=False) if upload == None: return template('error.tpl', error="server can't download from URL") # Set Project project = 'Main' db = Database() tf = tempfile.NamedTemporaryFile() tf.write(upload) if tf == None: return template('error.tpl', error="server can't download from URL") tf.flush() tf_obj = File(tf.name) tf_obj.name = tf_obj.sha256 new_path = store_sample(tf_obj) success = False if new_path: # Add file to the database. success = db.add(obj=tf_obj, tags=tags) if success: #redirect("/project/{0}".format(project)) redirect("/file/Main/" + tf_obj.sha256) else: return template('error.tpl', error="Unable to Store The File,already in database")
def post(self, request, *args, **kwargs): # Get the project and hash of the file we want to run a command against project = kwargs.get('project', 'default') file_hash = request.POST.get('file_hash') if len(file_hash) != 64: file_hash = False # Lot of logic here to decide what command you entered. module_name = request.POST.get('module') print("Here: {}".format(module_name)) if module_name == "module": return HttpResponse("<pre>Error: No Module selected!</pre>") module_args = request.POST.get('args') cmd_line = request.POST.get('cmdline') module_history = request.POST.get('moduleHistory', ' ') cmd_string = '' # Order of precedence # moduleHistory, cmd_line, module_name if module_history != ' ': result = Database().get_analysis(module_history) module_results = print_output(json.loads(result.results)) html = '<p class="text-success">Result for "{0}" stored on {1}</p>'.format(result.cmd_line, result.stored_at) html += str(parse_text(module_results)) return HttpResponse('<pre>{0}</pre>'.format(html)) if cmd_line: cmd_string = cmd_line elif module_args: cmd_string = '{0} {1}'.format(module_name, mod_dict[module_name][module_args]) module_results = module_cmdline(project=project, file_hash=file_hash, cmd_line=cmd_string) return HttpResponse('<pre>{0}</pre>'.format(str(parse_text(module_results))))
def size_cluster(self): db = Database() samples = db.find(key='all') cluster = {} for sample in samples: sample_path = get_sample_path(sample.sha256) if not os.path.exists(sample_path): continue try: cur_size = os.path.getsize(sample_path) except Exception as e: self.log('error', "Error {0} for sample {1}".format(e, sample.sha256)) continue if cur_size not in cluster: cluster[cur_size] = [] cluster[cur_size].append([sample.md5, sample.name]) for cluster_name, cluster_members in cluster.items(): # Skipping clusters with only one entry. if len(cluster_members) == 1: continue self.log( 'info', "Cluster size {0} with {1} elements".format( bold(cluster_name), len(cluster_members))) self.log('table', dict(header=['MD5', 'Name'], rows=cluster_members))
def size_scan(self): db = Database() samples = db.find(key='all') rows = [] for sample in samples: if sample.sha256 == __sessions__.current.file.sha256: continue sample_path = get_sample_path(sample.sha256) if not os.path.exists(sample_path): continue try: cur_size = os.path.getsize(sample_path) except: continue if self.file_size == cur_size: rows.append([sample.md5, sample.name]) if len(rows) > 0: self.log( 'info', "Following are samples with size {0}".format( bold(self.file_size))) self.log('table', dict(header=['MD5', 'Name'], rows=rows))
def cmd_tags(self, *args): parser = argparse.ArgumentParser( prog='tags', description="Modify tags of the opened file") parser.add_argument( '-a', '--add', metavar='TAG', help="Add tags to the opened file (comma separated)") parser.add_argument('-d', '--delete', metavar='TAG', help="Delete a tag from the opened file") try: args = parser.parse_args(args) except: return # This command requires a session to be opened. if not __sessions__.is_set(): self.log('error', "No open session") parser.print_usage() return # If no arguments are specified, there's not much to do. # However, it could make sense to also retrieve a list of existing # tags from this command, and not just from the "find" command alone. if args.add is None and args.delete is None: parser.print_usage() return # TODO: handle situation where addition or deletion of a tag fail. db = Database() if not db.find(key='sha256', value=__sessions__.current.file.sha256): self.log( 'error', "The opened file is not stored in the database. " "If you want to add it use the `store` command.") return if args.add: # Add specified tags to the database's entry belonging to # the opened file. db.add_tags(__sessions__.current.file.sha256, args.add) self.log('info', "Tags added to the currently opened file") # We refresh the opened session to update the attributes. # Namely, the list of tags returned by the 'info' command # needs to be re-generated, or it wouldn't show the new tags # until the existing session is closed a new one is opened. self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path) if args.delete: # Delete the tag from the database. db.delete_tag(args.delete, __sessions__.current.file.sha256) # Refresh the session so that the attributes of the file are # updated. self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path)
def add_file(self, file_path, tags, parent): obj = File(file_path) new_path = store_sample(obj) if new_path: # Add file to the database. db = Database() db.add(obj=obj, tags=tags, parent_sha=parent) return obj.sha256
def cmd_analysis(self, *args): parser = argparse.ArgumentParser(prog="analysis", description="Show stored module results") group = parser.add_mutually_exclusive_group() group.add_argument('-l', '--list', action='store_true', help="List all module results available for the current file") group.add_argument('-v', '--view', metavar='ANALYSIS ID', type=int, help="View the specified analysis") group.add_argument('-d', '--delete', metavar='ANALYSIS ID', type=int, help="Delete an existing analysis") try: args = parser.parse_args(args) except: return if not __sessions__.is_set(): self.log('error', "No open session") return # check if the file is already stores, otherwise exit malware = Database().find(key='sha256', value=__sessions__.current.file.sha256) if not malware: self.log('error', "The opened file doesn't appear to be in the database, have you stored it yet?") return if args.list: # Retrieve all analysis for the currently opened file. analysis_list = malware[0].analysis if not analysis_list: self.log('info', "No analysis available for this file yet") return # Populate table rows. rows = [[analysis.id, analysis.cmd_line, analysis.stored_at] for analysis in analysis_list] # Display list of existing results. self.log('table', dict(header=['ID', 'Cmd Line', 'Saved On'], rows=rows)) elif args.view: # Retrieve analysis wth the specified ID and print it. result = Database().get_analysis(args.view) if result: self.log('info', bold('Cmd Line: ') + result.cmd_line) for line in json.loads(result.results): self.log(line['type'], line['data']) else: self.log('info', "There is no analysis with ID {0}".format(args.view))
def cmd_projects(self, *args): parser = argparse.ArgumentParser( prog='projects', description="Open a file", epilog="List or switch existing projects") group = parser.add_mutually_exclusive_group() group.add_argument('-l', '--list', action='store_true', help="List all existing projects") group.add_argument('-s', '--switch', metavar='PROJECT NAME', help="Switch to the specified project") try: args = parser.parse_args(args) except: return projects_path = os.path.join(os.getcwd(), 'projects') if not os.path.exists(projects_path): self.log('info', "The projects directory does not exist yet") return if args.list: self.log('info', "Projects Available:") rows = [] for project in os.listdir(projects_path): project_path = os.path.join(projects_path, project) if os.path.isdir(project_path): current = '' if __project__.name and project == __project__.name: current = 'Yes' rows.append([ project, time.ctime(os.path.getctime(project_path)), current ]) self.log( 'table', dict(header=['Project Name', 'Creation Time', 'Current'], rows=rows)) elif args.switch: if __sessions__.is_set(): __sessions__.close() self.log('info', "Closed opened session") __project__.open(args.switch) self.log('info', "Switched to project {0}".format(bold(args.switch))) # Need to re-initialize the Database to open the new SQLite file. self.db = Database() else: self.log('info', parser.print_usage())
def _search_local_hashes(self, event, open_session=True): local = [] samples_count = 0 if event.get('Event') is None: self.log('error', event) return for a in event['Event']['Attribute']: row = None if a['type'] == 'malware-sample': samples_count += 1 if a['type'] in ('malware-sample', 'filename|md5', 'md5'): h = a['value'] if '|' in a['type']: h = a['value'].split('|')[1] row = Database().find(key='md5', value=h) elif a['type'] in ('sha1', 'filename|sha1'): h = a['value'] if '|' in a['type']: h = a['value'].split('|')[1] row = Database().find(key='sha1', value=h) elif a['type'] in ('sha256', 'filename|sha256'): h = a['value'] if '|' in a['type']: h = a['value'].split('|')[1] row = Database().find(key='sha256', value=h) if row: local.append(row[0]) self.log( 'info', 'Event {} contains {} samples.'.format(event['Event']['id'], samples_count)) if not open_session: return shas = set([l.sha256 for l in local]) if len(shas) == 1: __sessions__.new(get_sample_path(shas.pop()), MispEvent(event)) elif len(shas) > 1: self.log('success', 'The following samples are in this viper instance:') __sessions__.new(misp_event=MispEvent(event)) for s in shas: self.log('item', s) else: __sessions__.new(misp_event=MispEvent(event)) self.log('info', 'No known (in Viper) samples in that event.')
def test_notes_existing(self, capsys): self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) Database().add_note(__sessions__.current.file.sha256, 'Note test', 'This is the content') self.cmd['notes']['obj']('-l') self.cmd['notes']['obj']('-v', '1') self.cmd['notes']['obj']('-d', '1') out, err = capsys.readouterr() assert re.search(".*1 | Note test.*", out) assert re.search(".*This is the content.*", out)
def _add_file(file_path, name, tags, parent_sha): obj = File(file_path) new_path = store_sample(obj) if new_path: db = Database() db.add(obj=obj, name=name, tags=tags, parent_sha=parent_sha) return obj.sha256 else: return None
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return if not __sessions__.is_set(): self.log( 'error', "No open session. This command expects a file to be open.") return db = Database() # check if the file is already stores, otherwise exit malware = db.find(key='sha256', value=__sessions__.current.file.sha256) if not malware: self.log( 'error', "The opened file doesn't appear to be in the database, have you stored it yet?" ) return if args.list: # Retrieve all analysis for the currently opened file. analysis_list = malware[0].analysis if not analysis_list: self.log('info', "No analysis available for this file yet") return # Populate table rows. rows = [[analysis.id, analysis.cmd_line, analysis.stored_at] for analysis in analysis_list] # Display list of existing results. self.log( 'table', dict(header=['ID', 'Cmd Line', 'Saved On (UTC)'], rows=rows)) elif args.view: # Retrieve analysis wth the specified ID and print it. result = db.get_analysis(args.view) if result: self.log('info', bold('Cmd Line: ') + result.cmd_line) for line in json.loads(result.results): self.log(line['type'], line['data']) else: self.log('info', "There is no analysis with ID {0}".format(args.view)) elif args.delete: # Delete the analysis with the specified ID. db.delete_analysis(args.delete) else: self.parser.print_usage()