Пример #1
0
 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)
Пример #2
0
 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 }')
Пример #3
0
 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
Пример #4
0
 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')
Пример #5
0
 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)
Пример #6
0
 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)
Пример #7
0
 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
Пример #8
0
 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)
Пример #9
0
 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)
Пример #10
0
 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)
Пример #11
0
 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)
Пример #12
0
 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)
Пример #13
0
    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 (), ()
Пример #14
0
 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)