def take_action(self, parsed_args): logger.debug('[+] listing results') packet_cafe = get_packet_cafe(self.app, parsed_args) results = packet_cafe.get_results() if not len(results): raise RuntimeError('no results in packet_cafe server') if parsed_args.tree: root = Node(results[0].split("/")[1]) nodes = defaultdict() nodes[root.name] = root for file_path in sorted(results): self.add_node(file_path.lstrip('/'), nodes) try: for pre, _, node in RenderTree(root): print("%s%s" % (pre, node.name)) except BrokenPipeError: # Reopen stdout to avoid recurring exceptions sys.stdout = open(os.devnull, 'w') return ((), ()) else: columns = ['Results'] data = [] # Create a set of filters from args and options. contains = [ item for item in [parsed_args.tool, parsed_args.sess_id, parsed_args.req_id] if item is not None ] # Only select items that match all filters data = [[row] for row in results if match(line=row, contains=contains)] return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] deleting session data') packet_cafe = get_packet_cafe(self.app, parsed_args) ids = packet_cafe.get_session_ids() if ids is None or not len(ids): raise RuntimeError(NO_SESSIONS_MSG) if parsed_args.all: sess_ids = ids else: if (len(parsed_args.sess_id) and parsed_args.sess_id[0] is not None and not parsed_args.choose): sess_id = check_remind_defaulting(parsed_args.sess_id[0], 'last session id') else: sess_id = choose_wisely(from_list=ids, what="a session", cancel_throws_exception=True) if sess_id not in ids: raise RuntimeError(f'[-] session ID { sess_id } not found') sess_ids = [sess_id] for sess_id in sess_ids: result = packet_cafe.delete(sess_id=sess_id) if result is None: raise RuntimeError('[-] failed to delete ' f'session { sess_id }') # Do state files need to be deleted? # (Granted, this relies on a side-effect, but # c'est la vie. ¯\_(ツ)_/¯ ) _, _ = packet_cafe.get_last_session_id( ), packet_cafe.get_last_request_id() # noqa logger.info(f'[+] deleted session { sess_id }')
def take_action(self, parsed_args): logger.debug('[+] get tool output') packet_cafe = get_packet_cafe(self.app, parsed_args) ids = packet_cafe.get_session_ids() if not len(ids): raise RuntimeError(NO_SESSIONS_MSG) sess_id = packet_cafe.get_session_id( sess_id=parsed_args.sess_id, choose=parsed_args.choose ) if sess_id not in ids: raise RuntimeError( f'[-] session ID { sess_id } not found') req_id = packet_cafe.get_request_id( req_id=parsed_args.req_id, choose=parsed_args.choose ) tool = parsed_args.tool if tool is None: tools = packet_cafe.get_tools() tool = choose_wisely( from_list=tools, what="a tool", cancel_throws_exception=True ) results = packet_cafe.get_worker_output(tool=tool, counter=parsed_args.counter, sess_id=sess_id, req_id=req_id) try: print(results) except BrokenPipeError: pass
def take_action(self, parsed_args): logger.debug('[+] upload file') packet_cafe = get_packet_cafe(self.app, parsed_args) # Avoid the confusing double-negative if statement track_status = (self.app.options.verbose_level > 0 and parsed_args.no_track is not True) fpath = parsed_args.pcap[0] sess_id = packet_cafe.get_session_id( sess_id=parsed_args.sess_id, reuse_session=parsed_args.reuse_session, choose=parsed_args.choose, generate=True) if not os.path.exists(fpath): raise RuntimeError(f'[-] file { fpath } not found') result = packet_cafe.upload(fpath=fpath, sess_id=sess_id) if self.app.options.verbose_level > 0: # NOTE(dittrich): Don't forget: 'req_id' is 'uuid' in result readable_result = ( f"[+] Upload { result['filename'] }: { result['status'].lower() }\n" # noqa f"[+] Session ID (sess_id): { result['sess_id'] }\n" f"[+] Request ID (req_id): { result['uuid'] }") logger.info(readable_result) if track_status or parsed_args.wait: if not packet_cafe.track_progress( sess_id=result['sess_id'], req_id=result['uuid'], debug=self.app.options.debug, wait_only=parsed_args.wait, ignore_errors=parsed_args.ignore_errors, elapsed=self.app.options.elapsed): raise RuntimeError('[-] one or more jobs failed')
def take_action(self, parsed_args): logger.debug('[+] showing info (admin)') packet_cafe = get_packet_cafe(self.app, parsed_args) response = packet_cafe.get_admin_info() columns = ['url'] data = [packet_cafe.get_admin_url()] for k, v in response.items(): columns.append(k) data.append((v)) return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] listing session ids') packet_cafe = get_packet_cafe(self.app, parsed_args) columns = ['SessionId'] data = [[row] for row in packet_cafe.get_session_ids()] if not bool(len(data)): if bool(self.app_args.verbose_level): logger.info(NO_SESSIONS_MSG) sys.exit(1) if not bool(self.app_args.verbose_level): sys.exit(0) return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] get raw results') packet_cafe = get_packet_cafe(self.app, parsed_args) ids = packet_cafe.get_session_ids() if not len(ids): raise RuntimeError(NO_SESSIONS_MSG) sess_id = packet_cafe.get_session_id(sess_id=parsed_args.sess_id, choose=parsed_args.choose) if sess_id not in ids: raise RuntimeError(f'[-] session ID { sess_id } not found') req_id = packet_cafe.get_request_id(sess_id=parsed_args.sess_id, req_id=parsed_args.req_id, choose=parsed_args.choose) tool = parsed_args.tool if tool is None: tools = packet_cafe.get_tools() tool = choose_wisely(from_list=tools, what="a tool", cancel_throws_exception=True) results = packet_cafe.get_raw(tool=tool, counter=parsed_args.counter, sess_id=sess_id, req_id=req_id) if results is not None: if parsed_args.pprint: # pp = pprint.PrettyPrinter(indent=parsed_args.indent) # pp.print(results) pp = pprint.PrettyPrinter() try: pp.pprint(results) except BrokenPipeError: pass else: if parsed_args.nocolor or not sys.stdout.isatty(): try: print(json.dumps(results, indent=parsed_args.indent)) except BrokenPipeError: pass else: formatted_json = json.dumps(results, indent=parsed_args.indent) colored_json = highlight(formatted_json, lexers.JsonLexer(), formatters.TerminalFormatter()) try: print(colored_json) except BrokenPipeError: pass
def take_action(self, parsed_args): logger.debug('[+] listing request ids') packet_cafe = get_packet_cafe(self.app, parsed_args) ids = packet_cafe.get_session_ids() if len(ids) == 0: raise RuntimeError(NO_SESSIONS_MSG) sess_id = packet_cafe.get_session_id(sess_id=parsed_args.sess_id, choose=parsed_args.choose) if sess_id not in ids: raise RuntimeError(f'[-] session ID { sess_id } not found') # # NOTE(dittrich): The dictionary key "original_filename" differs # from other dictionaries that have "camel case" (e.g., # "viewableOutput" in the tools list), which complicates # capitalization of column headers. :( columns = ['Id', 'Filename', 'Original_Filename', 'Tools'] data = [] for row in packet_cafe.get_requests(sess_id=sess_id): data.append(([row[c.lower()] for c in columns])) return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] listing tools') packet_cafe = get_packet_cafe(self.app, parsed_args) columns = [ 'Name', 'Image', 'Version', 'Labels', 'Stage', 'ViewableOutput', 'Outputs', 'Inputs' ] repo_dir = parsed_args.packet_cafe_repo_dir branch = parsed_args.packet_cafe_repo_branch if parsed_args.definitions: logger.info("[+] definitions from workers.json file " f"in '{repo_dir}' (branch '{branch}')") workers_definitions = get_workers_definitions(repo_dir=repo_dir, flatten=True) workers = workers_definitions['workers'] else: workers = packet_cafe.get_workers() data = [] for worker in workers: data.append(([worker[c[0].lower() + c[1:]] for c in columns])) return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] listing files') packet_cafe = get_packet_cafe(self.app, parsed_args) files = packet_cafe.get_files() if not len(files): raise RuntimeError('no files in packet_cafe server') if parsed_args.tree: root = Node(files[0].split("/")[1]) nodes = defaultdict() nodes[root.name] = root for file_path in sorted(files): self.add_node(file_path.lstrip('/'), nodes) try: for pre, _, node in RenderTree(root): print("%s%s" % (pre, node.name)) except BrokenPipeError: # Reopen stdout to avoid recurring exceptions sys.stdout = open(os.devnull, 'w') return ((), ()) else: columns = ['File'] data = [[row] for row in packet_cafe.get_files()] return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] showing status for request') packet_cafe = get_packet_cafe(self.app, parsed_args) ids = packet_cafe.get_session_ids() if len(ids) == 0: raise RuntimeError(NO_SESSIONS_MSG) sess_id = packet_cafe.get_session_id(sess_id=parsed_args.sess_id, choose=parsed_args.choose) if sess_id not in ids: raise RuntimeError(f'[-] session ID { sess_id } not found') req_id = packet_cafe.get_request_id(req_id=parsed_args.req_id, choose=parsed_args.choose) columns = ['Tool', 'State', 'Timestamp'] data = [] status = packet_cafe.get_status(sess_id=sess_id, req_id=req_id) if status is None: raise RuntimeError('[-] failed to get status for ' f'session { sess_id }, ' f'request { req_id }') for k, v in status.items(): if type(v) is dict: data.append((k, v['state'], v['timestamp'])) return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] listing endpoints (api)') packet_cafe = get_packet_cafe(self.app, parsed_args) columns = ['Endpoint'] data = [[row] for row in packet_cafe.get_api_endpoints()] return (columns, data)
def take_action(self, parsed_args): logger.debug('[+] report on results from workers') packet_cafe = get_packet_cafe(self.app, parsed_args) ids = packet_cafe.get_session_ids() if not len(ids): raise RuntimeError(NO_SESSIONS_MSG) all_tools = packet_cafe.get_tools() if parsed_args.tool is not None: for tool in parsed_args.tool.split(','): if tool not in all_tools: raise RuntimeError( f"[-] no reportable output for tool '{ tool }'\n" f'[-] use one or more of: { ",".join(all_tools) }') sess_id = packet_cafe.get_session_id(sess_id=parsed_args.sess_id, choose=parsed_args.choose) if sess_id not in ids: raise RuntimeError(f'[-] session ID { sess_id } not found') req_id = packet_cafe.get_request_id(sess_id=sess_id, req_id=parsed_args.req_id, choose=parsed_args.choose) try: request = [ r for r in packet_cafe.get_requests(sess_id=sess_id) if r['id'] == req_id ][0] except IndexError: raise RuntimeError('[-] failed to get request details') # Save for reporting methods self.parsed_args = parsed_args if self.app_args.verbose_level >= 1: header_decorator = "*" * (len(request['filename']) + 21) try: print( textwrap.dedent(f""" { header_decorator } { " " * (int(len(header_decorator) / 2) - 8) }Packet Cafe Report Date produced: { arrow.utcnow() } Session ID: { sess_id } Request ID: { req_id } File: { request['filename']} Original File: { request['original_filename']} { header_decorator } """)) # noqa except BrokenPipeError: pass if parsed_args.tool is None: # Preserve report ordering. Because, CDO. # (It's like OCD, but the letters are in alphabetic order.) tools = [k for k in self.tool_function.keys() if k in all_tools] else: tools = parsed_args.tool.split(',') for tool in tools: results = packet_cafe.get_raw(tool=tool, sess_id=sess_id, req_id=req_id) self.summarize(tool=tool, results=results, sess_id=sess_id, req_id=req_id) # Return nothing as we have already output report subcomponents # directly. Kind of a hack, but what the hack? return (), ()
def take_action(self, parsed_args): self.log.debug('[+] opening packet-cafe UI') packet_cafe = get_packet_cafe(self.app, parsed_args) open_browser(page=packet_cafe.get_ui_url(), browser=parsed_args.browser, force=parsed_args.force)