示例#1
0
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,
                }
            )
示例#2
0
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))
示例#3
0
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))
示例#4
0
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")
示例#5
0
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')
示例#6
0
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(
示例#7
0
文件: cli.py 项目: ehtrashy/fcreplay
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)
示例#8
0
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))
示例#9
0
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}"
            )
示例#10
0
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))
示例#11
0
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)
示例#12
0
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