def module_cmdline(cmd_line, file_hash): 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: 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 as e: html += '<p class="text-danger">We were unable to complete the command {0}</p>'.format(cmd_line) __sessions__.close() return html
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 run(self, *args): try: self.parser.parse_args(args) except SystemExit: return __sessions__.close()
def module_cmdline(cmd_line, file_hash): 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: path = get_sample_path(file_hash) __sessions__.new(path) module = __modules__[root]['obj']() module.set_commandline(args) module.run() html += print_output(module.output) del (module.output[:]) else: html += '<p class="text-danger">{0} is not a valid command</p>'.format( cmd_line) except: html += '<p class="text-danger">We were unable to complete the command {0}</p>'.format( cmd_line) __sessions__.close() return html
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") return if not __project__.name: src_project = "default" else: src_project = __project__.name db.copied_id_sha256 = [] res = db.copy(__sessions__.current.file.id, src_project=src_project, dst_project=args.project, copy_analysis=True, copy_notes=True, copy_tags=True, copy_children=args.children) if args.delete: __sessions__.close() for item_id, item_sha256 in db.copied_id_sha256: db.delete_file(item_id) os.remove(get_sample_path(item_sha256)) self.log('info', "Deleted: {}".format(item_sha256)) if res: self.log('success', "Successfully copied sample(s)") return True else: self.log('error', "Something went wrong") return False
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 cmd_delete(self, *args): parser = argparse.ArgumentParser(prog='delete', description="Delete a file") parser.add_argument('-a', '--all', action='store_true', help="Delete ALL files in this project") parser.add_argument('-f', '--find', action="store_true", help="Delete ALL files from last find") try: args = parser.parse_args(args) except: return while True: choice = input("Are you sure? It can't be reverted! [y/n] ") if choice == 'y': break elif choice == 'n': return if args.all: if __sessions__.is_set(): __sessions__.close() samples = self.db.find('all') for sample in samples: self.db.delete_file(sample.id) os.remove(get_sample_path(sample.sha256)) self.log('info', "Deleted a total of {} files.".format(len(samples))) elif args.find: if __sessions__.find: samples = __sessions__.find for sample in samples: self.db.delete_file(sample.id) os.remove(get_sample_path(sample.sha256)) self.log('info', "Deleted {} files.".format(len(samples))) else: self.log('error', "No find result") else: if __sessions__.is_set(): rows = self.db.find('sha256', __sessions__.current.file.sha256) if rows: malware_id = rows[0].id if self.db.delete_file(malware_id): self.log("success", "File deleted") else: self.log('error', "Unable to delete file") os.remove(__sessions__.current.file.path) __sessions__.close() self.log('info', "Deleted opened file.") else: self.log('error', "No session open, and no --all argument. Nothing to delete.")
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return while True: choice = input("Are you sure? It can't be reverted! [y/n] ") if choice == 'y': break elif choice == 'n': return db = Database() if args.all: if __sessions__.is_set(): __sessions__.close() samples = db.find('all') for sample in samples: db.delete_file(sample.id) os.remove(get_sample_path(sample.sha256)) self.log('info', "Deleted a total of {} files.".format(len(samples))) elif args.find: if __sessions__.find: samples = __sessions__.find for sample in samples: db.delete_file(sample.id) os.remove(get_sample_path(sample.sha256)) self.log('info', "Deleted {} files.".format(len(samples))) else: self.log('error', "No find result") else: if __sessions__.is_set(): rows = db.find('sha256', __sessions__.current.file.sha256) if rows: malware_id = rows[0].id if db.delete_file(malware_id): self.log("success", "File deleted") else: self.log('error', "Unable to delete file") os.remove(__sessions__.current.file.path) __sessions__.close() self.log('info', "Deleted opened file.") else: self.log('error', "No session open, and no --all argument. Nothing to delete.")
def file_info(file_hash, project=False): contents = {} if project in project_list(): __project__.open(project) contents['project'] = project else: __project__.open('../') contents['project'] = 'Main' # Open the Database db = Database() # Open a session try: path = get_sample_path(file_hash) __sessions__.new(path) except: return template('error.tpl', error="{0} Does not match any hash in the Database".format(file_hash)) # Get the file info contents['file_info'] = [ __sessions__.current.file.name, __sessions__.current.file.tags, __sessions__.current.file.path, __sessions__.current.file.size, __sessions__.current.file.type, __sessions__.current.file.mime, __sessions__.current.file.md5, __sessions__.current.file.sha1, __sessions__.current.file.sha256, __sessions__.current.file.sha512, __sessions__.current.file.ssdeep, __sessions__.current.file.crc32 ] # Get Any Notes note_list = [] malware = db.find(key='sha256', value=file_hash) if malware: notes = malware[0].note if notes: rows = [] for note in notes: note_list.append([note.title, note.body, note.id]) contents['notes'] = note_list # Close the session __sessions__.close() # Return the page return template('file.tpl', **contents)
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 cfg = Config() if cfg.paths.storage_path: base_path = cfg.paths.storage_path else: base_path = os.path.join(expanduser("~"), '.viper') projects_path = os.path.join(base_path, '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 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 cmd_delete(self, *args): parser = argparse.ArgumentParser(prog='delete', description="Delete a file") parser.add_argument('-a', '--all', action='store_true', help="Delete ALL files in this project") try: args = parser.parse_args(args) except: return while True: choice = input("Are you sure? It can't be reverted! [y/n] ") if choice == 'y': break elif choice == 'n': return if args.all: if __sessions__.is_set(): __sessions__.close() samples = self.db.find('all') for sample in samples: self.db.delete_file(sample.id) os.remove(get_sample_path(sample.sha256)) self.log('info', "Deleted a total of {} files.".format(len(samples))) else: if __sessions__.is_set(): rows = self.db.find('sha256', __sessions__.current.file.sha256) if rows: malware_id = rows[0].id if self.db.delete_file(malware_id): self.log("success", "File deleted") else: self.log('error', "Unable to delete file") os.remove(__sessions__.current.file.path) __sessions__.close() self.log('info', "Deleted opened file.") else: self.log('error', "No session open, and no --all argument. Nothing to delete.")
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return if cfg.get('paths').storage_path: base_path = cfg.get('paths').storage_path else: base_path = os.path.join(expanduser("~"), '.viper') projects_path = os.path.join(base_path, 'projects') if args.list: if not os.path.exists(projects_path): self.log('info', "The projects directory does not exist yet") return 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. db.__init__() else: self.log('info', self.parser.print_usage())
def add_file(file_path, tags, parent): obj = File(file_path) new_path = store_sample(obj) print new_path success = True if new_path: # Add file to the database. db = Database() success = db.add(obj=obj, tags=tags, parent_sha=parent) # 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: # ToDo Remove the stored file if we cant write to DB return
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 if not __project__.name: src_project = "default" else: src_project = __project__.name db = Database() db.copied_id_sha256 = [] res = db.copy(__sessions__.current.file.id, src_project=src_project, dst_project=args.project, copy_analysis=True, copy_notes=True, copy_tags=True, copy_children=args.children) if args.delete: __sessions__.close() for item_id, item_sha256 in db.copied_id_sha256: db.delete_file(item_id) os.remove(get_sample_path(item_sha256)) self.log('info', "Deleted: {}".format(item_sha256)) if res: self.log('success', "Successfully copied sample(s)") return True else: self.log('error', "Something went wrong") return False
def cmd_delete(self, *args): if __sessions__.is_set(): while True: choice = raw_input("Are you sure you want to delete this binary? Can't be reverted! [y/n] ") if choice == 'y': break elif choice == 'n': return rows = self.db.find('sha256', __sessions__.current.file.sha256) if rows: malware_id = rows[0].id if self.db.delete_file(malware_id): self.log("success", "File deleted") else: self.log('error', "Unable to delete file") os.remove(__sessions__.current.file.path) __sessions__.close() else: self.log('error', "No session opened")
def module_text(file_hash, cmd_string): # A lot of commands rely on an open session # open a session on the file hash path = get_sample_path(file_hash) __sessions__.new(path) # Run the Module with args if __sessions__.is_set(): root, args = parse(cmd_string) if root in __modules__: module = __modules__[root]['obj']() module.set_args(args) module.run() html = print_output(module.output) del(module.output[:]) else: html = '<p class="text-danger">{0} is not a valid command</p>'.format(cmd_string) else: '<p class="text-danger">! There is no open session</p>' # close the session __sessions__.close() return html
def run_module(): # Optional Project project = request.forms.get('project') # Optional sha256 sha256 = request.forms.get('sha256') # Not Optional Command Line Args cmd_line = request.forms.get('cmdline') if project: __project__.open(project) else: __project__.open('../') if sha256: file_path = get_sample_path(sha256) if file_path: __sessions__.new(file_path) if not cmd_line: response.code = 404 return jsonize({'message':'Invalid command line'}) results = module_cmdline(cmd_line, sha256) __sessions__.close() return jsonize(results)
def module_text(cmd_string, file_hash): # A lot of commands rely on an open session # open a session on the file hash path = get_sample_path(file_hash) __sessions__.new(path) # Run the Module with args if __sessions__.is_set(): root, args = parse(cmd_string) if root in __modules__: module = __modules__[root]['obj']() module.set_commandline(args) module.run() html = print_output(module.output) del(module.output[:]) else: html = '<p class="text-danger">{0} is not a valid command</p>'.format(cmd_string) else: '<p class="text-danger">! There is no open session</p>' # close the session __sessions__.close() return html
def cmd_delete(self, *args): if __sessions__.is_set(): while True: choice = raw_input("Are you sure you want to delete this binary? Can't be reverted! [y/n] ") if choice == "y": break elif choice == "n": return rows = self.db.find("sha256", __sessions__.current.file.sha256) if rows: malware_id = rows[0].id if self.db.delete(malware_id): print_success("File deleted") else: print_error("Unable to delete file") os.remove(__sessions__.current.file.path) __sessions__.close() else: print_error("No session opened")
def module_cmdline(cmd_line, sha256): json_data = '' 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 = [] # Split words by white space. words = split_command.split() # First word is the root command. root = words[0] # If there are more words, populate the arguments list. if len(words) > 1: args = words[1:] try: if root in cmd.commands: cmd.commands[root]['obj'](*args) if cmd.output: json_data += str(cmd.output) del(cmd.output[:]) elif root in __modules__: # if prev commands did not open a session open one on the current file if sha256: path = get_sample_path(sha256) __sessions__.new(path) module = __modules__[root]['obj']() module.set_commandline(args) module.run() json_data += str(module.output) del(module.output[:]) else: json_data += "{'message':'{0} is not a valid command'.format(cmd_line)}" except: json_data += "{'message':'Unable to complete the command: {0}'.format(cmd_line)}" __sessions__.close() return json_data
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_to_run = cmd.commands[root]['obj'] cmd_to_run(*args) cmd_instance = cmd_to_run.__self__ html += print_output(cmd_instance.output) del (cmd_instance.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, __project__) __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 module_text(file_hash, cmd_string): # redirect stdout to a memory file sys.stdout = StringIO() # A lot of commands rely on an open session # open a session on the file hash path = get_sample_path(file_hash) __sessions__.new(path) # Run the Module with args, the ouptut will end up in a StringIO Object if __sessions__.is_set(): root, args = parse(cmd_string) if root in __modules__: module = __modules__[root]['obj']() module.set_args(args) module.run() # Parse the raw data to something we can use clean_text = parse_text(sys.stdout.getvalue()) # close the session __sessions__.close() return clean_text
def add_file(file_path, name=None, url=None, tags=None, parent=None): obj = File(file_path, url) new_path = store_sample(obj) print(new_path) if not name: name = os.path.basename(file_path) # success = True if new_path: # Add file to the database. db = Database() db.add(obj=obj, name=name, tags=tags, url=url, parent_sha=parent) # 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: # ToDo Remove the stored file if we cant write to DB return
def cmd_store(self, *args): parser = argparse.ArgumentParser( prog='store', description="Store the opened file to the local repository") parser.add_argument('-d', '--delete', action='store_true', help="Delete the original file") parser.add_argument('-f', '--folder', type=str, nargs='+', help="Specify a folder to import") parser.add_argument('-s', '--file-size', type=int, help="Specify a maximum file size") parser.add_argument('-y', '--file-type', type=str, help="Specify a file type pattern") parser.add_argument('-n', '--file-name', type=str, help="Specify a file name pattern") parser.add_argument('-t', '--tags', type=str, nargs='+', help="Specify a list of comma-separated tags") try: args = parser.parse_args(args) except: return if args.folder is not None: # Allows to have spaces in the path. args.folder = " ".join(args.folder) if args.tags is not None: # Remove the spaces in the list of tags args.tags = "".join(args.tags) def add_file(obj, tags=None): if get_sample_path(obj.sha256): self.log( 'warning', "Skip, file \"{0}\" appears to be already stored".format( obj.name)) return False if __sessions__.is_attached_misp(quiet=True): if tags is not None: tags += ',misp:{}'.format( __sessions__.current.misp_event.event_id) else: tags = 'misp:{}'.format( __sessions__.current.misp_event.event_id) # Try to store file object into database. status = self.db.add(obj=obj, tags=tags) if status: # If succeeds, store also in the local repository. # If something fails in the database (for example unicode strings) # we don't want to have the binary lying in the repository with no # associated database record. new_path = store_sample(obj) self.log( "success", "Stored file \"{0}\" to {1}".format(obj.name, new_path)) else: return False # Delete the file if requested to do so. if args.delete: try: os.unlink(obj.path) except Exception as e: self.log('warning', "Failed deleting file: {0}".format(e)) return True # If the user specified the --folder flag, we walk recursively and try # to add all contained files to the local repository. # This is note going to open a new session. # TODO: perhaps disable or make recursion optional? if args.folder is not None: # Check if the specified folder is valid. if os.path.isdir(args.folder): # Walk through the folder and subfolders. for dir_name, dir_names, file_names in walk(args.folder): # Add each collected file. for file_name in file_names: file_path = os.path.join(dir_name, file_name) if not os.path.exists(file_path): continue # Check if file is not zero. if not os.path.getsize(file_path) > 0: continue # Check if the file name matches the provided pattern. if args.file_name: if not fnmatch.fnmatch(file_name, args.file_name): # self.log('warning', "Skip, file \"{0}\" doesn't match the file name pattern".format(file_path)) continue # Check if the file type matches the provided pattern. if args.file_type: if args.file_type not in File(file_path).type: # self.log('warning', "Skip, file \"{0}\" doesn't match the file type".format(file_path)) continue # Check if file exceeds maximum size limit. if args.file_size: # Obtain file size. if os.path.getsize(file_path) > args.file_size: self.log( 'warning', "Skip, file \"{0}\" is too big".format( file_path)) continue file_obj = File(file_path) # Add file. add_file(file_obj, args.tags) if add_file and cfg.autorun.enabled: autorun_module(file_obj.sha256) # Close the open session to keep the session table clean __sessions__.close() else: self.log( 'error', "You specified an invalid folder: {0}".format(args.folder)) # Otherwise we try to store the currently opened file, if there is any. else: if __sessions__.is_set(): if __sessions__.current.file.size == 0: self.log( 'warning', "Skip, file \"{0}\" appears to be empty".format( __sessions__.current.file.name)) return False # Add file. if add_file(__sessions__.current.file, args.tags): # Open session to the new file. self.cmd_open(*[__sessions__.current.file.sha256]) if cfg.autorun.enabled: autorun_module(__sessions__.current.file.sha256) else: self.log('error', "No open session")
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return if args.folder is not None: # Allows to have spaces in the path. args.folder = " ".join(args.folder) if args.tags is not None: # Remove the spaces in the list of tags args.tags = "".join(args.tags) def add_file(obj, tags=None): if get_sample_path(obj.sha256): self.log('warning', "Skip, file \"{0}\" appears to be already stored".format(obj.name)) return False if __sessions__.is_attached_misp(quiet=True): if tags is not None: tags += ',misp:{}'.format(__sessions__.current.misp_event.event.id) else: tags = 'misp:{}'.format(__sessions__.current.misp_event.event.id) # Try to store file object into database. status = db.add(obj=obj, tags=tags) if status: # If succeeds, store also in the local repository. # If something fails in the database (for example unicode strings) # we don't want to have the binary lying in the repository with no # associated database record. new_path = store_sample(obj) self.log("success", "Stored file \"{0}\" to {1}".format(obj.name, new_path)) else: return False # Delete the file if requested to do so. if args.delete: try: os.unlink(obj.path) except Exception as e: self.log('warning', "Failed deleting file: {0}".format(e)) return True # If the user specified the --folder flag, we walk recursively and try # to add all contained files to the local repository. # This is note going to open a new session. # TODO: perhaps disable or make recursion optional? if args.folder is not None: # Check if the specified folder is valid. if os.path.isdir(args.folder): # Walk through the folder and subfolders. for dir_name, dir_names, file_names in walk(args.folder): # Add each collected file. for file_name in file_names: file_path = os.path.join(dir_name, file_name) if not os.path.exists(file_path): continue # Check if file is not zero. if not os.path.getsize(file_path) > 0: continue # Check if the file name matches the provided pattern. if args.file_name: if not fnmatch.fnmatch(file_name, args.file_name): # self.log('warning', "Skip, file \"{0}\" doesn't match the file name pattern".format(file_path)) continue # Check if the file type matches the provided pattern. if args.file_type: if args.file_type not in File(file_path).type: # self.log('warning', "Skip, file \"{0}\" doesn't match the file type".format(file_path)) continue # Check if file exceeds maximum size limit. if args.file_size: # Obtain file size. if os.path.getsize(file_path) > args.file_size: self.log('warning', "Skip, file \"{0}\" is too big".format(file_path)) continue file_obj = File(file_path) # Add file. add_file(file_obj, args.tags) if add_file and cfg.get('autorun').enabled: autorun_module(file_obj.sha256) # Close the open session to keep the session table clean __sessions__.close() else: self.log('error', "You specified an invalid folder: {0}".format(args.folder)) # Otherwise we try to store the currently opened file, if there is any. else: if __sessions__.is_set(): if __sessions__.current.file.size == 0: self.log('warning', "Skip, file \"{0}\" appears to be empty".format(__sessions__.current.file.name)) return False # Add file. if add_file(__sessions__.current.file, args.tags): # Open session to the new file. Open().run(*[__sessions__.current.file.sha256]) if cfg.get('autorun').enabled: autorun_module(__sessions__.current.file.sha256) else: self.log('error', "No open session")
def cmd_projects(self, *args): def usage(): print("usage: projects [-h] [-l] [-s=project]") def help(): usage() print("") print("Options:") print("\t--help (-h)\tShow this help message") print("\t--list (-l)\tList all existing projects") print("\t--switch (-s)\tSwitch to the specified project") print("") try: opts, argv = getopt.getopt(args, "hls:", ["help", "list", "switch="]) except getopt.GetoptError as e: print(e) usage() return arg_list = False arg_switch = None for opt, value in opts: if opt in ("-h", "--help"): help() return elif opt in ("-l", "--list"): arg_list = True elif opt in ("-s", "--switch"): arg_switch = value projects_path = os.path.join(os.getcwd(), "projects") if not os.path.exists(projects_path): print_info("The projects directory does not exist yet") return if arg_list: print_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]) print(table(header=["Project Name", "Creation Time", "Current"], rows=rows)) return elif arg_switch: if __sessions__.is_set(): __sessions__.close() print_info("Closed opened session") __project__.open(arg_switch) print_info("Switched to project {0}".format(bold(arg_switch))) # Need to re-initialize the Database to open the new SQLite file. self.db = Database() return usage()
def cmd_close(self, *args): __sessions__.close()
def teardown_method(self): __sessions__.close()
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return if __config__.get("paths").storage_path: base_path = __config__.get("paths").storage_path else: base_path = os.path.join(expanduser("~"), ".viper") projects_path = os.path.join(base_path, "projects") if args.list: if not os.path.exists(projects_path): self.log("info", "No projects have been created yet") return 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. Database().__init__() elif args.close: if __project__.name != "default": if __sessions__.is_set(): __sessions__.close() __project__.close() elif args.delete: project_to_delete = args.delete if project_to_delete == "default": self.log("error", "You can't delete the \"default\" project") return # If it"s the currently opened project, we close it. if project_to_delete == __project__.name: # We close any opened session. if __sessions__.is_set(): __sessions__.close() __project__.close() project_path = os.path.join(projects_path, project_to_delete) if not os.path.exists(project_path): self.log( "error", "The folder for project \"{}\" does not seem to exist". format(project_to_delete)) return self.log( "info", "You asked to delete project with name \"{}\" located at \"{}\"" .format(project_to_delete, project_path)) confirm = input( "Are you sure you want to delete the project? You will permanently delete all associated files! [y/N] " ) if confirm.lower() != "y": return try: shutil.rmtree(project_path) except Exception as e: self.log( "error", "Something failed while trying to delete folder: {}". format(e)) return self.log( "info", "Project \"{}\" was delete successfully".format( project_to_delete)) else: self.log("info", self.parser.print_usage())
def store(self): try: event_path = os.path.join(self.cur_path, 'misp_events') if not os.path.exists(event_path): os.mkdir(event_path) if self.args.list: header = ['Event ID', 'Title'] rows = [] for eid, path, title in self._get_local_events(event_path): rows.append((eid, title)) self.log( 'table', dict(header=header, rows=sorted(rows, key=lambda i: (int(i[0].split('_')[-1]))))) elif self.args.update: if self.offline_mode: self.log('error', 'Offline mode, cannot update locally stored events.') return for eid, path, title in self._get_local_events(event_path): event = self.misp.get(eid) with open(path, 'w') as f: f.write(json.dumps(event)) self.log('success', '{} updated successfully.'.format(eid)) elif self.args.sync: if self.offline_mode: self.log( 'error', 'Offline mode, cannot synchronize locally stored events.') return for eid, path, title in self._get_local_events(event_path): __sessions__.close() event = MISPEvent() event.load(path) if 'new_event_' in path: event = self.misp.add_event(event.to_json()) try: self._dump(event) os.remove(path) except Exception as e: self.log('error', 'Unable to create new event: {}.'.format(e)) else: eid = event.id try: event = self.misp.update(event._json()) except Exception as e: self.log( 'error', 'Unable to update event {}: {}.'.format(eid, e)) if self._has_error_message(event): return elif self.args.delete: path = os.path.join(event_path, '{}.json'.format(self.args.delete)) if os.path.exists(path): os.remove(path) self.log('success', '{} removed successfully.'.format(self.args.delete)) else: self.log('error', '{} does not exists.'.format(self.args.delete)) elif self.args.open: filename = '{}.json'.format(self.args.open) path = os.path.join(event_path, filename) if os.path.exists(path): try: with open(path, 'r') as f: e_json = json.load(f) __sessions__.new( misp_event=MispEvent(e_json, self.offline_mode)) __sessions__.current.misp_event.current_dump_file = filename except Exception as e: self.log('error', 'Unable to open {}: {}'.format(path, e)) else: self.log('error', '{} does not exists.'.format(self.args.open)) elif __sessions__.is_attached_misp(): self._dump() except IOError as e: self.log('error', e.strerror)
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return if __config__.get('paths').storage_path: base_path = __config__.get('paths').storage_path else: base_path = os.path.join(expanduser("~"), '.viper') projects_path = os.path.join(base_path, 'projects') if args.list: if not os.path.exists(projects_path): self.log('info', "The projects directory does not exist yet") return 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. Database().__init__() elif args.close: if __project__.name != "default": if __sessions__.is_set(): __sessions__.close() __project__.close() elif args.delete: project_to_delete = args.delete if project_to_delete == "default": self.log('error', "You can't delete the \"default\" project") return # If it's the currently opened project, we close it. if project_to_delete == __project__.name: # We close any opened session. if __sessions__.is_set(): __sessions__.close() __project__.close() project_path = os.path.join(projects_path, project_to_delete) if not os.path.exists(project_path): self.log('error', "The folder for project \"{}\" does not seem to exist".format(project_to_delete)) return self.log('info', "You asked to delete project with name \"{}\" located at \"{}\"".format(project_to_delete, project_path)) confirm = input("Are you sure you want to delete the project? You will permanently delete all associated files! [y/N] ") if confirm.lower() != 'y': return try: shutil.rmtree(project_path) except Exception as e: self.log('error', "Something failed while trying to delete folder: {}".format(e)) return self.log('info', "Project \"{}\" was delete successfully".format(project_to_delete)) else: self.log('info', self.parser.print_usage())
def store(self): try: event_path = os.path.join(self.cur_path, 'misp_events') if not os.path.exists(event_path): os.mkdir(event_path) if self.args.list: header = ['Event ID', 'Title'] rows = [] for eid, path, title in self._get_local_events(event_path): rows.append((eid, title)) self.log('table', dict(header=header, rows=sorted(rows, key=lambda i: (int(i[0].split('_')[-1]))))) elif self.args.update: if self.offline_mode: self.log('error', 'Offline mode, cannot update locally stored events.') return for eid, path, title in self._get_local_events(event_path): event = self.misp.get(eid) with open(path, 'w') as f: f.write(json.dumps(event)) self.log('success', '{} updated successfully.'.format(eid)) elif self.args.sync: if self.offline_mode: self.log('error', 'Offline mode, cannot synchronize locally stored events.') return for eid, path, title in self._get_local_events(event_path): __sessions__.close() event = MISPEvent() event.load(path) if 'new_event_' in path: event = self.misp.add_event(json.dumps(event, cls=EncodeUpdate)) try: self._dump(event) os.remove(path) except Exception as e: self.log('error', 'Unable to create new event: {}.'.format(e)) else: eid = event.id try: event = self.misp.update(event._json()) except Exception as e: self.log('error', 'Unable to update event {}: {}.'.format(eid, e)) if self._has_error_message(event): return elif self.args.delete: path = os.path.join(event_path, '{}.json'.format(self.args.delete)) if os.path.exists(path): os.remove(path) self.log('success', '{} removed successfully.'.format(self.args.delete)) else: self.log('error', '{} does not exists.'.format(self.args.delete)) elif self.args.open: filename = '{}.json'.format(self.args.open) path = os.path.join(event_path, filename) if os.path.exists(path): try: with open(path, 'r') as f: e_json = json.load(f) __sessions__.new(misp_event=MispEvent(e_json, self.offline_mode)) __sessions__.current.misp_event.current_dump_file = filename except Exception as e: self.log('error', 'Unable to open {}: {}'.format(path, e)) else: self.log('error', '{} does not exists.'.format(self.args.open)) elif __sessions__.is_attached_misp(): self._dump() except IOError as e: self.log('error', e.strerror)
def cmd_projects(self, *args): def usage(): print("usage: projects [-h] [-l] [-s=project]") def help(): usage() print("") print("Options:") print("\t--help (-h)\tShow this help message") print("\t--list (-l)\tList all existing projects") print("\t--switch (-s)\tSwitch to the specified project") print("") try: opts, argv = getopt.getopt(args, 'hls:', ['help', 'list', 'switch=']) except getopt.GetoptError as e: print(e) usage() return arg_list = False arg_switch = None for opt, value in opts: if opt in ('-h', '--help'): help() return elif opt in ('-l', '--list'): arg_list = True elif opt in ('-s', '--switch'): arg_switch = value projects_path = os.path.join(os.getcwd(), 'projects') if not os.path.exists(projects_path): print_info("The projects directory does not exist yet") return if arg_list: print_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 ]) print( table(header=['Project Name', 'Creation Time', 'Current'], rows=rows)) return elif arg_switch: if __sessions__.is_set(): __sessions__.close() print_info("Closed opened session") __project__.open(arg_switch) print_info("Switched to project {0}".format(bold(arg_switch))) # Need to re-initialize the Database to open the new SQLite file. self.db = Database() return usage()
def cmd_store(self, *args): parser = argparse.ArgumentParser(prog='store', description="Store the opened file to the local repository") parser.add_argument('-d', '--delete', action='store_true', help="Delete the original file") parser.add_argument('-f', '--folder', type=str, nargs='+', help="Specify a folder to import") parser.add_argument('-s', '--file-size', type=int, help="Specify a maximum file size") parser.add_argument('-y', '--file-type', type=str, help="Specify a file type pattern") parser.add_argument('-n', '--file-name', type=str, help="Specify a file name pattern") parser.add_argument('-t', '--tags', type=str, nargs='+', help="Specify a list of comma-separated tags") try: args = parser.parse_args(args) except: return if args.folder is not None: # Allows to have spaces in the path. args.folder = " ".join(args.folder) if args.tags is not None: # Remove the spaces in the list of tags args.tags = "".join(args.tags) def add_file(obj, tags=None): if get_sample_path(obj.sha256): self.log('warning', "Skip, file \"{0}\" appears to be already stored".format(obj.name)) return False # Try to store file object into database. status = self.db.add(obj=obj, tags=tags) if status: # If succeeds, store also in the local repository. # If something fails in the database (for example unicode strings) # we don't want to have the binary lying in the repository with no # associated database record. new_path = store_sample(obj) self.log("success", "Stored file \"{0}\" to {1}".format(obj.name, new_path)) else: return False # Delete the file if requested to do so. if args.delete: try: os.unlink(obj.path) except Exception as e: self.log('warning', "Failed deleting file: {0}".format(e)) return True # If the user specified the --folder flag, we walk recursively and try # to add all contained files to the local repository. # This is note going to open a new session. # TODO: perhaps disable or make recursion optional? if args.folder is not None: # Check if the specified folder is valid. if os.path.isdir(args.folder): # Walk through the folder and subfolders. for dir_name, dir_names, file_names in walk(args.folder): # Add each collected file. for file_name in file_names: file_path = os.path.join(dir_name, file_name) if not os.path.exists(file_path): continue # Check if file is not zero. if not os.path.getsize(file_path) > 0: continue # Check if the file name matches the provided pattern. if args.file_name: if not fnmatch.fnmatch(file_name, args.file_name): # self.log('warning', "Skip, file \"{0}\" doesn't match the file name pattern".format(file_path)) continue # Check if the file type matches the provided pattern. if args.file_type: if args.file_type not in File(file_path).type: # self.log('warning', "Skip, file \"{0}\" doesn't match the file type".format(file_path)) continue # Check if file exceeds maximum size limit. if args.file_size: # Obtain file size. if os.path.getsize(file_path) > args.file_size: self.log('warning', "Skip, file \"{0}\" is too big".format(file_path)) continue file_obj = File(file_path) # Add file. add_file(file_obj, args.tags) if add_file and cfg.autorun.enabled: autorun_module(file_obj.sha256) # Close the open session to keep the session table clean __sessions__.close() else: self.log('error', "You specified an invalid folder: {0}".format(args.folder)) # Otherwise we try to store the currently opened file, if there is any. else: if __sessions__.is_set(): if __sessions__.current.file.size == 0: self.log('warning', "Skip, file \"{0}\" appears to be empty".format(__sessions__.current.file.name)) return False # Add file. if add_file(__sessions__.current.file, args.tags): # Open session to the new file. self.cmd_open(*[__sessions__.current.file.sha256]) if cfg.autorun.enabled: autorun_module(__sessions__.current.file.sha256) else: self.log('error', "No session opened")