class ReportsCommands(cmd2.CommandSet): def __init__(self): super().__init__() report_parser = cmd2.Cmd2ArgumentParser() report_parser.add_argument( "-w", "--workspace-name", type=str, help="Workspace" ) report_parser.add_argument( "--create-workspace", action="store_true", help="Create the workspace it not exists", ) report_parser.add_argument( "--plugin-id", type=str, help="Plugin ID (force detection)", required=False, ) report_parser.add_argument( "-j", "--json-output", action="store_true", help="Show output in json (dont send to faraday)", ) report_parser.add_argument( "--tag-vuln", type=str, help="Tag to add to vulnerabilities", required=False, ) report_parser.add_argument( "--tag-host", type=str, help="Tag to add to hosts", required=False, ) report_parser.add_argument( "--tag-service", type=str, help="Tag to add to services", required=False, ) report_parser.add_argument("report_path", help="Path of the report file") @cmd2.as_subcommand_to( "tool", "report", report_parser, help="process a report from a tool" ) def process_report(self, args: argparse.Namespace): """Process Tool report in Faraday""" report_path = Path(args.report_path) if not report_path.is_file(): self._cmd.perror(f"File {report_path} dont exists") return if not args.json_output: if not args.workspace_name: if active_config.workspace: workspace_name = active_config.workspace else: self._cmd.perror("No active Workspace") return else: workspace_name = args.workspace_name if not self._cmd.api_client.is_workspace_available(workspace_name): if not args.create_workspace: self._cmd.perror(f"Invalid workspace: {workspace_name}") return else: try: self._cmd.api_client.create_workspace(workspace_name) self._cmd.poutput( cmd2.style( f"Workspace {workspace_name} created", fg=COLORS.GREEN, ) ) except Exception as e: self._cmd.perror(f"Error creating workspace: {e}") return else: destination_workspace = workspace_name else: destination_workspace = workspace_name if args.plugin_id: plugin = self._cmd.plugins_manager.get_plugin(args.plugin_id) if not plugin: self._cmd.perror(f"Invalid Plugin: {args.plugin_id}") return else: plugin = self._cmd.report_analyzer.get_plugin(report_path) if not plugin: self._cmd.perror( f"{self._cmd.emojis['cross']} " f"Failed to detect report: {report_path}" ) return if not args.json_output: self._cmd.poutput( cmd2.style( f"{self._cmd.emojis['page']} " f"Processing {plugin.id} report", fg=COLORS.GREEN, ) ) plugin.processReport( report_path.absolute().as_posix(), getpass.getuser() ) report_json = apply_tags( plugin.get_data(), args.tag_host, args.tag_service, args.tag_vuln ) if args.json_output: self._cmd.poutput(json.dumps(report_json, indent=4)) else: self._cmd.data_queue.put( { "workspace": destination_workspace, "json_data": report_json, } )
class SubcommandApp(cmd2.Cmd): """ Example cmd2 application where we a base command which has a couple subcommands.""" def __init__(self): cmd2.Cmd.__init__(self) # subcommand functions for the base command def base_foo(self, args): """foo subcommand of base command""" self.poutput(args.x * args.y) def base_bar(self, args): """bar subcommand of base command""" self.poutput('((%s))' % args.z) def base_helpless(self, args): """helpless subcommand of base command""" self.poutput('((%s))' % args.z) # create the top-level parser for the base command base_parser = argparse.ArgumentParser() base_subparsers = base_parser.add_subparsers(dest='subcommand', metavar='SUBCOMMAND') base_subparsers.required = True # create the parser for the "foo" subcommand parser_foo = base_subparsers.add_parser('foo', help='foo help') parser_foo.add_argument('-x', type=int, default=1, help='integer') parser_foo.add_argument('y', type=float, help='float') parser_foo.set_defaults(func=base_foo) # create the parser for the "bar" subcommand parser_bar = base_subparsers.add_parser('bar', help='bar help', aliases=['bar_1', 'bar_2']) parser_bar.add_argument('z', help='string') parser_bar.set_defaults(func=base_bar) # create the parser for the "helpless" subcommand # This subcommand has aliases and no help text. It exists to prevent changes to _set_parser_prog() which # use an approach which relies on action._choices_actions list. See comment in that function for more # details. parser_bar = base_subparsers.add_parser('helpless', aliases=['helpless_1', 'helpless_2']) parser_bar.add_argument('z', help='string') parser_bar.set_defaults(func=base_bar) @cmd2.with_argparser(base_parser) def do_base(self, args): """Base command help""" # Call whatever subcommand function was selected func = getattr(args, 'func') func(self, args) # Add subcommands using as_subcommand_to decorator has_subcmds_parser = cmd2.Cmd2ArgumentParser(description="Tests as_subcmd_to decorator") has_subcmds_subparsers = has_subcmds_parser.add_subparsers(dest='subcommand', metavar='SUBCOMMAND') has_subcmds_subparsers.required = True @cmd2.with_argparser(has_subcmds_parser) def do_test_subcmd_decorator(self, args: argparse.Namespace): handler = args.cmd2_handler.get() handler(args) subcmd_parser = cmd2.Cmd2ArgumentParser(description="A subcommand") @cmd2.as_subcommand_to('test_subcmd_decorator', 'subcmd', subcmd_parser, help=subcmd_parser.description.lower()) def subcmd_func(self, args: argparse.Namespace): # Make sure printing the Namespace works. The way we originally added cmd2_hander to it resulted in a RecursionError. self.poutput(args) helpless_subcmd_parser = cmd2.Cmd2ArgumentParser(add_help=False, description="A subcommand with no help") @cmd2.as_subcommand_to('test_subcmd_decorator', 'helpless_subcmd', helpless_subcmd_parser, help=helpless_subcmd_parser.description.lower()) def helpless_subcmd_func(self, args: argparse.Namespace): # Make sure vars(Namespace) works. The way we originally added cmd2_hander to it resulted in a RecursionError. self.poutput(vars(args))
class ArgumentAndOptionPrinter(cmd2.Cmd): """Example cmd2 application where we create commands that just print the arguments they are called with.""" def __init__(self): # Create command shortcuts which are typically 1 character abbreviations which can be used in place of a command shortcuts = dict(cmd2.DEFAULT_SHORTCUTS) shortcuts.update({'$': 'aprint', '%': 'oprint'}) super().__init__(shortcuts=shortcuts) def do_aprint(self, statement): """Print the argument string this basic command is called with.""" self.poutput('aprint was called with argument: {!r}'.format(statement)) self.poutput('statement.raw = {!r}'.format(statement.raw)) self.poutput('statement.argv = {!r}'.format(statement.argv)) self.poutput('statement.command = {!r}'.format(statement.command)) @cmd2.with_argument_list def do_lprint(self, arglist): """Print the argument list this basic command is called with.""" self.poutput( 'lprint was called with the following list of arguments: {!r}'. format(arglist)) @cmd2.with_argument_list(preserve_quotes=True) def do_rprint(self, arglist): """Print the argument list this basic command is called with (with quotes preserved).""" self.poutput( 'rprint was called with the following list of arguments: {!r}'. format(arglist)) oprint_parser = cmd2.Cmd2ArgumentParser() oprint_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay') oprint_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE') oprint_parser.add_argument('-r', '--repeat', type=int, help='output [n] times') oprint_parser.add_argument('words', nargs='+', help='words to print') @cmd2.with_argparser(oprint_parser) def do_oprint(self, args): """Print the options and argument list this options command was called with.""" self.poutput( 'oprint was called with the following\n\toptions: {!r}'.format( args)) pprint_parser = cmd2.Cmd2ArgumentParser() pprint_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay') pprint_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE') pprint_parser.add_argument('-r', '--repeat', type=int, help='output [n] times') @cmd2.with_argparser(pprint_parser, with_unknown_args=True) def do_pprint(self, args, unknown): """Print the options and argument list this options command was called with.""" self.poutput( 'oprint was called with the following\n\toptions: {!r}\n\targuments: {}' .format(args, unknown))
class CommandSetA(CommandSetBase): def on_register(self, cmd) -> None: super().on_register(cmd) print("in on_register now") def on_registered(self) -> None: super().on_registered() print("in on_registered now") def on_unregister(self) -> None: super().on_unregister() print("in on_unregister now") def on_unregistered(self) -> None: super().on_unregistered() print("in on_unregistered now") def do_apple(self, statement: cmd2.Statement): self._cmd.poutput('Apple!') def do_banana(self, statement: cmd2.Statement): """Banana Command""" self._cmd.poutput('Banana!!') cranberry_parser = cmd2.Cmd2ArgumentParser() cranberry_parser.add_argument('arg1', choices=['lemonade', 'juice', 'sauce']) @cmd2.with_argparser(cranberry_parser, with_unknown_args=True) def do_cranberry(self, ns: argparse.Namespace, unknown: List[str]): self._cmd.poutput('Cranberry {}!!'.format(ns.arg1)) if unknown and len(unknown): self._cmd.poutput('Unknown: ' + ', '.join(['{}'] * len(unknown)).format(*unknown)) self._cmd.last_result = {'arg1': ns.arg1, 'unknown': unknown} def help_cranberry(self): self._cmd.stdout.write('This command does diddly squat...\n') @cmd2.with_argument_list @cmd2.with_category('Also Alone') def do_durian(self, args: List[str]): """Durian Command""" self._cmd.poutput('{} Arguments: '.format(len(args))) self._cmd.poutput(', '.join(['{}'] * len(args)).format(*args)) self._cmd.last_result = {'args': args} def complete_durian(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: return self._cmd.basic_complete(text, line, begidx, endidx, ['stinks', 'smells', 'disgusting']) elderberry_parser = cmd2.Cmd2ArgumentParser() elderberry_parser.add_argument('arg1') @cmd2.with_category('Alone') @cmd2.with_argparser(elderberry_parser) def do_elderberry(self, ns: argparse.Namespace): self._cmd.poutput('Elderberry {}!!'.format(ns.arg1)) self._cmd.last_result = {'arg1': ns.arg1} # Test that CommandSet with as_subcommand_to decorator successfully loads # during `cmd2.Cmd.__init__()`. main_parser = cmd2.Cmd2ArgumentParser(description="Main Command") main_subparsers = main_parser.add_subparsers(dest='subcommand', metavar='SUBCOMMAND') main_subparsers.required = True @cmd2.with_category('Alone') @cmd2.with_argparser(main_parser) def do_main(self, args: argparse.Namespace) -> None: # Call handler for whatever subcommand was selected handler = args.cmd2_handler.get() handler(args) # main -> sub subcmd_parser = cmd2.Cmd2ArgumentParser(description="Sub Command") @cmd2.as_subcommand_to('main', 'sub', subcmd_parser, help="sub command") def subcmd_func(self, args: argparse.Namespace) -> None: self._cmd.poutput("Subcommand Ran")
class LoadableBase(cmd2.CommandSet): def __init__(self, dummy): super(LoadableBase, self).__init__() self._dummy = dummy # prevents autoload self._cut_called = False cut_parser = cmd2.Cmd2ArgumentParser() cut_subparsers = cut_parser.add_subparsers(title='item', help='item to cut') def namespace_provider(self) -> argparse.Namespace: ns = argparse.Namespace() ns.cut_called = self._cut_called return ns @cmd2.with_argparser(cut_parser) def do_cut(self, ns: argparse.Namespace): """Cut something""" handler = ns.cmd2_handler.get() if handler is not None: # Call whatever subcommand function was selected handler(ns) self._cut_called = True else: # No subcommand was provided, so call help self._cmd.pwarning( 'This command does nothing without sub-parsers registered') self._cmd.do_help('cut') stir_parser = cmd2.Cmd2ArgumentParser() stir_subparsers = stir_parser.add_subparsers(title='item', help='what to stir') @cmd2.with_argparser(stir_parser, ns_provider=namespace_provider) def do_stir(self, ns: argparse.Namespace): """Stir something""" if not ns.cut_called: self._cmd.poutput('Need to cut before stirring') return handler = ns.cmd2_handler.get() if handler is not None: # Call whatever subcommand function was selected handler(ns) else: # No subcommand was provided, so call help self._cmd.pwarning( 'This command does nothing without sub-parsers registered') self._cmd.do_help('stir') stir_pasta_parser = cmd2.Cmd2ArgumentParser() stir_pasta_parser.add_argument('--option', '-o') stir_pasta_parser.add_subparsers(title='style', help='Stir style') @cmd2.as_subcommand_to('stir', 'pasta', stir_pasta_parser) def stir_pasta(self, ns: argparse.Namespace): handler = ns.cmd2_handler.get() if handler is not None: # Call whatever subcommand function was selected handler(ns) else: self._cmd.poutput('Stir pasta haphazardly')
import socket import cmd2 from .config import defaults from .helpers import get_scans from ..tools import tools # options for ReconShell's 'status' command status_parser = cmd2.Cmd2ArgumentParser() status_parser.add_argument( "--port", help= "port on which the luigi central scheduler's visualization site is running (default: 8082)", default="8082", ) status_parser.add_argument( "--host", help= "host on which the luigi central scheduler's visualization site is running (default: localhost)", default="127.0.0.1", ) # options for ReconShell's 'scan' command scan_parser = cmd2.Cmd2ArgumentParser() scan_parser.add_argument("scantype", choices_function=get_scans, help="which type of scan to run") target_group = scan_parser.add_mutually_exclusive_group(required=True) target_group.add_argument(
class Cli(cmd2.Cmd): def __init__(self): super().__init__() # Show this as the prompt when asking for input self.prompt = 'fcreplay> ' # Used as prompt for multiline commands after the first line self.continuation_prompt = '... ' self.db = Database() add_replay_parser = cmd2.Cmd2ArgumentParser(description='Add a new replay') add_replay_parser.add_argument('replay_url', help='Replay url of replay') delete_failed_parser = cmd2.Cmd2ArgumentParser( description='Delete a failed replay') delete_failed_parser.add_argument('challenge_id', help='Challenge id of replay') delete_all_failed_parser = cmd2.Cmd2ArgumentParser( description='Delete all failed replays') delete_all_failed_parser.add_argument('-y', '--yes', action='store_true', help='Force yes') delete_pending_parser = cmd2.Cmd2ArgumentParser( description='Delete a pending replay') delete_pending_parser.add_argument('challenge_id', help='Challenge id of the replay') delete_all_pending_parser = cmd2.Cmd2ArgumentParser( description='Delete all pending replays') delete_all_pending_parser.add_argument('-y', '--yes', action='store_true', help='Force yes') retry_replay_parser = cmd2.Cmd2ArgumentParser( description='Mark a replay to be re-encoded') retry_replay_parser.add_argument('challenge_id', help='Challenge id of replay') retry_all_failed_replays_parser = cmd2.Cmd2ArgumentParser( description='Mark all failed replays to be re-encoded') retry_all_failed_replays_parser.add_argument('-y', '--yes', action='store_true', help='Force yes') list_replays_parser = cmd2.Cmd2ArgumentParser(description='List replays') list_replays_parser.add_argument('type', type=str, nargs=1, choices=['failed', 'finished', 'pending'], help='Type of replays to return') list_replays_parser.add_argument('-l', '--limit', default=10, type=int, help='Limit number of results') count_parser = cmd2.Cmd2ArgumentParser(description='List replays') count_parser.add_argument('type', type=str, nargs=1, choices=['failed', 'finished', 'pending', 'all'], help='Type of replays to count') def yes_or_no(self, question): while "the answer is invalid": reply = str(input(question + ' continue? (y/n): ')).lower().strip() if reply[:1] == 'y': return True if reply[:1] == 'n': return False @cmd2.with_argparser(add_replay_parser) def do_add_replay(self, args): Getreplay().get_replay(args.replay_url) return @cmd2.with_argparser(delete_failed_parser) def do_delete_failed(self, args): if self.yes_or_no( f"This will delete failed replay: {args.challenge_id},"): replay = self.db.get_single_replay(args.challenge_id) if replay is not None: if replay.failed is True: self.db.delete_replay(args.challenge_id) print(f"Deleated replay {args.challenge_id}") else: print(f"Replay {args.challenge_id} isn't a faild replay") return else: print(f"Replay {args.challenge_id} doesn't exist") return @cmd2.with_argparser(delete_all_failed_parser) def do_delete_all_failed(self, args): if not args.yes: if not self.yes_or_no("This will delete all failed replays,"): return failed_replays = self.db.get_all_failed_replays(limit=9999) if failed_replays is not None: for r in failed_replays: self.db.delete_replay(r.id) print(f"Removed replay: {r.id}") else: print("No failed replays") return @cmd2.with_argparser(delete_pending_parser) def do_delete_pending(self, args): if self.yes_or_no( f"This will delete the pending replay: {args.challenge_id},"): replay = self.db.get_single_replay(args.challenge_id) if replay is not None: if replay.failed is not True and replay.finished is not True: self.db.delete_replay(replay.id) else: print("Replay isn't a pending replay") return else: print("No replay found") return @cmd2.with_argparser(delete_all_pending_parser) def do_delete_all_pending(self, args): if not args.yes: if not self.yes_or_no("This will delete all pending replays,"): return pending_replays = self.db.get_all_queued_replays(limit=9999) if pending_replays is not None: for r in pending_replays: self.db.delete_replay(r.id) print(f"Removed replay: {r.id}") else: print("No pending replays") return @cmd2.with_argparser(retry_replay_parser) def do_retry_replay(self, args): replay = self.db.get_single_replay(args.challenge_id) if replay is not None: self.db.rerecord_replay(args.challenge_id) print(f"Marked replay {args.challenge_id} to be re-encoded") else: print(f"Replay {args.challenge_id} doesn't exist") @cmd2.with_argparser(retry_all_failed_replays_parser) def do_retry_all_failed_replays(self, args): if not args.yes: if not self.yes_or_no("This will retry all failed replays,"): return failed_replays = self.db.get_all_failed_replays(limit=1000) if failed_replays is None: print("No failed replays to retry") else: for r in failed_replays: self.db.rerecord_replay(r.id) print(f"Marked failed replay {r.id} to be re-encoded") @cmd2.with_argparser(list_replays_parser) def do_ls(self, args): replays = None if 'failed' in args.type: replays = self.db.get_all_failed_replays(limit=args.limit) elif 'finished' in args.type: replays = self.db.get_all_finished_replays(limit=args.limit) elif 'pending' in args.type: replays = self.db.get_all_queued_replays(limit=args.limit) else: return if replays is not None: pp = pprint.PrettyPrinter() for r in replays: pp.pprint(r.__dict__) else: print(f"No replays found for query: {args}") @cmd2.with_argparser(count_parser) def do_count(self, args): replay_count = None if 'failed' in args.type: replay_count = self.db.get_failed_count() elif 'finished' in args.type: replay_count = self.db.get_finished_count() elif 'pending' in args.type: replay_count = self.db.get_pending_count() elif 'all' in args.type: replay_count = self.db.get_all_count() if replay_count is None: print("0") else: print(replay_count)
class CmdLineApp(cmd2.Cmd): """Example cmd2 application.""" # Setting this true makes it run a shell command if a cmd2/cmd command doesn't exist # default_to_shell = True MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh'] MUMBLE_FIRST = ['so', 'like', 'well'] MUMBLE_LAST = ['right?'] def __init__(self): shortcuts = dict(cmd2.DEFAULT_SHORTCUTS) shortcuts.update({'&': 'speak'}) # Set include_ipy to True to enable the "ipy" command which runs an interactive IPython shell super().__init__(allow_cli_args=False, include_ipy=True, multiline_commands=['orate'], shortcuts=shortcuts) self.self_in_py = True self.maxrepeats = 3 # Make maxrepeats settable at runtime self.add_settable(cmd2.Settable('maxrepeats', int, 'max repetitions for speak command', self)) speak_parser = cmd2.Cmd2ArgumentParser() speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay') speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE') speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times') speak_parser.add_argument('words', nargs='+', help='words to say') @cmd2.with_argparser(speak_parser) def do_speak(self, args): """Repeats what you tell me to.""" words = [] for word in args.words: if args.piglatin: word = '%s%say' % (word[1:], word[0]) if args.shout: word = word.upper() words.append(word) repetitions = args.repeat or 1 for i in range(min(repetitions, self.maxrepeats)): # .poutput handles newlines, and accommodates output redirection too self.poutput(' '.join(words)) do_say = do_speak # now "say" is a synonym for "speak" do_orate = do_speak # another synonym, but this one takes multi-line input mumble_parser = cmd2.Cmd2ArgumentParser() mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat') mumble_parser.add_argument('words', nargs='+', help='words to say') @cmd2.with_argparser(mumble_parser) def do_mumble(self, args): """Mumbles what you tell me to.""" repetitions = args.repeat or 1 for i in range(min(repetitions, self.maxrepeats)): output = [] if random.random() < 0.33: output.append(random.choice(self.MUMBLE_FIRST)) for word in args.words: if random.random() < 0.40: output.append(random.choice(self.MUMBLES)) output.append(word) if random.random() < 0.25: output.append(random.choice(self.MUMBLE_LAST)) self.poutput(' '.join(output))
class ToolCommands(cmd2.CommandSet): def __init__(self): super().__init__() tool_parser = cmd2.Cmd2ArgumentParser() tool_parser.add_argument( "-w", "--workspace-name", type=str, help="Workspace" ) tool_parser.add_argument( "--create-workspace", action="store_true", help="Create the workspace it not exists", ) tool_parser.add_argument( "--plugin-id", type=str, help="Plugin ID (force detection)", required=False, ) tool_parser.add_argument( "-j", "--json-output", action="store_true", help="Show output in json (dont send it to faraday)", ) tool_parser.add_argument( "--tag-vuln", type=str, help="Tag to add to vulnerabilities", required=False, ) tool_parser.add_argument( "--tag-host", type=str, help="Tag to add to hosts", required=False, ) tool_parser.add_argument( "--tag-service", type=str, help="Tag to add to services", required=False, ) tool_parser.add_argument("command", help="Command of the tool to process") @cmd2.as_subcommand_to( "tool", "run", tool_parser, help="run a tool and process it" ) def process_tool(self, args): """Process Tool execution in Faraday""" if not args.json_output: if not args.workspace_name: if active_config.workspace: workspace_name = active_config.workspace else: self._cmd.perror("No active Workspace") return else: workspace_name = args.workspace_name if not self._cmd.api_client.is_workspace_available(workspace_name): if not args.create_workspace: self._cmd.perror(f"Invalid workspace: {workspace_name}") return else: try: self._cmd.api_client.create_workspace(workspace_name) self._cmd.poutput( cmd2.style( f"Workspace {workspace_name} created", fg=COLORS.GREEN, ) ) except Exception as e: self._cmd.perror(f"Error creating workspace: {e}") return else: destination_workspace = workspace_name else: destination_workspace = workspace_name if args.plugin_id: plugin = self._cmd.plugins_manager.get_plugin(args.plugin_id) if not plugin: self._cmd.perror(f"Invalid Plugin: {args.plugin_id}") return else: plugin = self._cmd.command_analyzer.get_plugin(args.command) if plugin: if not args.json_output: self._cmd.poutput( cmd2.style( f"{self._cmd.emojis['laptop']} " f"Processing {plugin.id} command", fg=COLORS.GREEN, ) ) show_command_output = not args.json_output command_json = utils.run_tool( plugin, getpass.getuser(), args.command, show_output=show_command_output, ) if not command_json: self._cmd.perror( f"{self._cmd.emojis['cross']} Command execution error!!" ) else: command_json = utils.apply_tags( command_json, args.tag_host, args.tag_service, args.tag_vuln, ) if args.json_output: self._cmd.poutput(json.dumps(command_json, indent=4)) else: self._cmd.data_queue.put( { "workspace": destination_workspace, "json_data": command_json, } ) else: self._cmd.perror( f"Could not detect plugin for command: {args.command}" )
class ArgparseApp(cmd2.Cmd): def __init__(self): self.maxrepeats = 3 cmd2.Cmd.__init__(self) def namespace_provider(self) -> argparse.Namespace: ns = argparse.Namespace() ns.custom_stuff = "custom" return ns say_parser = cmd2.Cmd2ArgumentParser() say_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay') say_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE') say_parser.add_argument('-r', '--repeat', type=int, help='output [n] times') say_parser.add_argument('words', nargs='+', help='words to say') @cmd2.with_argparser(say_parser) def do_say(self, args, *, keyword_arg: Optional[str] = None): """Repeat what you tell me to.""" words = [] for word in args.words: if word is None: word = '' if args.piglatin: word = '%s%say' % (word[1:], word[0]) if args.shout: word = word.upper() words.append(word) repetitions = args.repeat or 1 for i in range(min(repetitions, self.maxrepeats)): self.stdout.write(' '.join(words)) self.stdout.write('\n') if keyword_arg is not None: print(keyword_arg) tag_parser = cmd2.Cmd2ArgumentParser(description='create a html tag') tag_parser.add_argument('tag', help='tag') tag_parser.add_argument('content', nargs='+', help='content to surround with tag') @cmd2.with_argparser(tag_parser, preserve_quotes=True) def do_tag(self, args): self.stdout.write('<{0}>{1}</{0}>'.format(args.tag, ' '.join(args.content))) self.stdout.write('\n') @cmd2.with_argparser(cmd2.Cmd2ArgumentParser(), ns_provider=namespace_provider) def do_test_argparse_ns(self, args): self.stdout.write('{}'.format(args.custom_stuff)) @cmd2.with_argument_list def do_arglist(self, arglist, *, keyword_arg: Optional[str] = None): if isinstance(arglist, list): self.stdout.write('True') else: self.stdout.write('False') if keyword_arg is not None: print(keyword_arg) @cmd2.with_argument_list(preserve_quotes=True) def do_preservelist(self, arglist): self.stdout.write('{}'.format(arglist)) known_parser = cmd2.Cmd2ArgumentParser() known_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay') known_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE') known_parser.add_argument('-r', '--repeat', type=int, help='output [n] times') @cmd2.with_argparser(known_parser, with_unknown_args=True) def do_speak(self, args, extra, *, keyword_arg: Optional[str] = None): """Repeat what you tell me to.""" words = [] for word in extra: if word is None: word = '' if args.piglatin: word = '%s%say' % (word[1:], word[0]) if args.shout: word = word.upper() words.append(word) repetitions = args.repeat or 1 for i in range(min(repetitions, self.maxrepeats)): self.stdout.write(' '.join(words)) self.stdout.write('\n') if keyword_arg is not None: print(keyword_arg) @cmd2.with_argparser(cmd2.Cmd2ArgumentParser(), preserve_quotes=True, with_unknown_args=True) def do_test_argparse_with_list_quotes(self, args, extra): self.stdout.write('{}'.format(' '.join(extra))) @cmd2.with_argparser(cmd2.Cmd2ArgumentParser(), ns_provider=namespace_provider, with_unknown_args=True) def do_test_argparse_with_list_ns(self, args, extra): self.stdout.write('{}'.format(args.custom_stuff))
class VulnerabilityCommands(cmd2.CommandSet): def __init__(self): super().__init__() # List Vulnerabilities list_vulns_parser = cmd2.Cmd2ArgumentParser() list_vulns_parser.add_argument("-j", "--json-output", action="store_true", help="Show output in json") list_vulns_parser.add_argument( "-p", "--pretty", action="store_true", help="Show table in a pretty format", ) list_vulns_parser.add_argument("-w", "--workspace-name", type=str, help="Workspace") list_vulns_parser.add_argument( "--ignore-info", action="store_true", help=f"Ignore {'/'.join(IGNORE_SEVERITIES)} vulnerabilities", ) list_vulns_parser.add_argument( "--severity", type=str, help=f"Filter by severity {'/'.join(SEVERITIES)}", default=[], nargs="*", ) list_vulns_parser.add_argument( "--confirmed", action="store_true", help="Show confirmed vulnerabilities", ) @cmd2.as_subcommand_to("vuln", "list", list_vulns_parser, help="list vulnerabilities") def list_vulns(self, args: argparse.Namespace): """List Vulnerabilities""" @Halo( text="Gathering data", text_color="green", spinner="dots", stream=sys.stderr, ) def get_data(workspace_name, filter_to_apply): vulns = self._cmd.api_client.get_vulns(workspace_name, filter_to_apply) return vulns if not args.workspace_name: if active_config.workspace: workspace_name = active_config.workspace else: self._cmd.perror("No active Workspace") return else: workspace_name = args.workspace_name query_filter = FaradayFilter() selected_severities = set(map(lambda x: x.lower(), args.severity)) if selected_severities: for severity in selected_severities: if severity not in SEVERITIES: self._cmd.perror(f"Invalid severity: {severity}") return else: query_filter.require_severity(severity) if args.ignore_info: for severity in IGNORE_SEVERITIES: query_filter.ignore_severity(severity) if args.confirmed: query_filter.filter_confirmed() filter_to_apply = query_filter.get_filter() try: vulns = get_data(workspace_name, filter_to_apply) except NotFoundError: self._cmd.perror("Workspace not found") else: if args.json_output: self._cmd.poutput( json.dumps(vulns["vulnerabilities"], indent=4)) else: if not vulns["count"]: self._cmd.perror( f"No vulnerabilities in workspace: {workspace_name}") else: data = [ OrderedDict({ "ID": x["id"], "NAME": x["value"]["name"], "SEVERITY": cmd2.style( x["value"]["severity"].upper(), fg=utils.get_severity_color( x["value"]["severity"]), ), "STATUS": x["value"]["status"], "CONFIRMED": x["value"]["confirmed"], "ASSET": f"{x['value']['target']} [{x['value']['parent_type']} " # noqa: E501 + ( f"- ID:{x['value']['parent']}]" if x["value"]["parent_type"] == "Host" else f"- {x['value']['service']['summary']}]" # noqa: E501 ), "HOSTNAMES": "\n".join(x["value"]["hostnames"]), }) for x in vulns["vulnerabilities"] ] self._cmd.print_output( tabulate( data, headers="keys", tablefmt="psql" if args.pretty else "simple", )) # Add evidence to Vulnerability add_evidence_parser = cmd2.Cmd2ArgumentParser() add_evidence_parser.add_argument("image", type=str, help="Path of the image") add_evidence_parser.add_argument("-w", "--workspace-name", type=str, help="Workspace") add_evidence_parser.add_argument( "-id", "--vulnerability-id", type=int, help="Vulnerability ID", required=True, ) @cmd2.as_subcommand_to( "vuln", "add-evidence", add_evidence_parser, help="add evidence to vulnerability", ) def add_evidence(self, args: argparse.Namespace): """Add evidence to Vulnerability""" if not args.workspace_name: if active_config.workspace: workspace_name = active_config.workspace else: self._cmd.perror("No active Workspace") return else: workspace_name = args.workspace_name image_path = Path(args.image) if not image_path.is_file(): self._cmd.perror(f"File {args.image} not found") return self._cmd.api_client.get_vuln(workspace_name, args.vulnerability_id) try: response = self._cmd.api_client.upload_evidence_to_vuln( workspace_name, args.vulnerability_id, args.image) self._cmd.poutput(response["message"]) except RequestError as e: self._cmd.perror(e.message)
class CmdLineApp(cmd2.Cmd): """Example cmd2 application to showcase conditional control flow in Python scripting within cmd2 apps.""" def __init__(self): # Set include_ipy to True to enable the "ipy" command which runs an interactive IPython shell super().__init__(include_ipy=True) self._set_prompt() self.intro = 'Happy 𝛑 Day. Note the full Unicode support: 😇 💩' def _set_prompt(self): """Set prompt so it displays the current working directory.""" self.cwd = os.getcwd() self.prompt = ansi.style(f'{self.cwd} $ ', fg='cyan') def postcmd(self, stop: bool, line: str) -> bool: """Hook method executed just after a command dispatch is finished. :param stop: if True, the command has indicated the application should exit :param line: the command line text for this command :return: if this is True, the application will exit after this command and the postloop() will run """ """Override this so prompt always displays cwd.""" self._set_prompt() return stop @cmd2.with_argument_list def do_cd(self, arglist): """Change directory. Usage: cd <new_dir> """ # Expect 1 argument, the directory to change to if not arglist or len(arglist) != 1: self.perror("cd requires exactly 1 argument:") self.do_help('cd') self.last_result = 'Bad arguments' return # Convert relative paths to absolute paths path = os.path.abspath(os.path.expanduser(arglist[0])) # Make sure the directory exists, is a directory, and we have read access err = None data = None if not os.path.isdir(path): err = f'{path} is not a directory' elif not os.access(path, os.R_OK): err = f'You do not have read access to {path}' else: try: os.chdir(path) except Exception as ex: err = f'{ex}' else: self.poutput(f'Successfully changed directory to {path}') data = path if err: self.perror(err) self.last_result = data # Enable tab completion for cd command def complete_cd(self, text, line, begidx, endidx): # Tab complete only directories return self.path_complete(text, line, begidx, endidx, path_filter=os.path.isdir) dir_parser = cmd2.Cmd2ArgumentParser() dir_parser.add_argument('-l', '--long', action='store_true', help="display in long format with one item per line") @cmd2.with_argparser(dir_parser, with_unknown_args=True) def do_dir(self, args, unknown): """List contents of current directory.""" # No arguments for this command if unknown: self.perror("dir does not take any positional arguments:") self.do_help('dir') self.last_result = 'Bad arguments' return # Get the contents as a list contents = os.listdir(self.cwd) for f in contents: self.poutput(f'{f}') self.poutput('') self.last_result = contents