コード例 #1
0
ファイル: cli.py プロジェクト: redcat8850/pyrdp
def configure(cmdline=None) -> MITMConfig:
    parser = buildArgParser()

    if cmdline:
        args = parser.parse_args(cmdline)
    else:
        args = parser.parse_args()

    # Load configuration file.
    cfg = settings.load(settings.CONFIG_DIR + '/mitm.ini', DEFAULTS)

    # Override some of the switches based on command line arguments.
    if args.output:
        cfg.set('vars', 'output_dir', args.output)
    if args.log_filter:
        cfg.set('logs', 'filter', args.log_filter)
    if args.log_level:
        cfg.set('vars', 'level', args.log_level)
    if args.sensor_id:
        cfg.set('vars', 'sensor_id', args.sensor_id)

    outDir = Path(cfg.get('vars', 'output_dir'))
    outDir.mkdir(exist_ok=True)

    configureLoggers(cfg)
    logger = logging.getLogger(LOGGER_NAMES.PYRDP)

    if args.target is None and not args.transparent:
        parser.print_usage()
        sys.stderr.write(
            'error: A relay target is required unless running in transparent proxy mode.\n'
        )
        sys.exit(1)

    if (args.nla_redirection_host is None) != (args.nla_redirection_port is
                                               None):
        sys.stderr.write(
            'Error: please provide both --nla-redirection-host and --nla-redirection-port'
        )
        sys.exit(1)

    if args.target:
        targetHost, targetPort = parseTarget(args.target)
    else:
        targetHost = None
        targetPort = 3389  # FIXME: Allow to set transparent port as well.

    key, certificate = validateKeyAndCertificate(args.private_key,
                                                 args.certificate)

    config = MITMConfig()
    config.targetHost = targetHost
    config.targetPort = targetPort
    config.privateKeyFileName = key
    config.listenPort = int(args.listen)
    config.certificateFileName = certificate
    config.attackerHost = args.destination_ip
    config.attackerPort = int(args.destination_port)
    config.replacementUsername = args.username
    config.replacementPassword = args.password
    config.outDir = outDir
    config.enableCrawler = args.crawl
    config.crawlerMatchFileName = args.crawler_match_file
    config.crawlerIgnoreFileName = args.crawler_ignore_file
    config.recordReplays = not args.no_replay
    config.downgrade = not args.no_downgrade
    config.transparent = args.transparent
    config.extractFiles = not args.no_files
    config.disableActiveClipboardStealing = args.disable_active_clipboard
    config.useGdi = not args.no_gdi
    config.redirectionHost = args.nla_redirection_host
    config.redirectionPort = args.nla_redirection_port

    payload = None
    powershell = None

    npayloads = int(args.payload is not None) + \
        int(args.payload_powershell is not None) + \
        int(args.payload_powershell_file is not None)

    if npayloads > 1:
        logger.error(
            "Only one of --payload, --payload-powershell and --payload-powershell-file may be supplied."
        )
        sys.exit(1)

    if args.payload is not None:
        payload = args.payload
        logger.info("Using payload: %(payload)s", {"payload": args.payload})
    elif args.payload_powershell is not None:
        powershell = args.payload_powershell
        logger.info("Using powershell payload: %(payload)s",
                    {"payload": args.payload_powershell})
    elif args.payload_powershell_file is not None:
        if not os.path.exists(args.payload_powershell_file):
            logger.error("Powershell file %(path)s does not exist.",
                         {"path": args.payload_powershell_file})
            sys.exit(1)

        try:
            with open(args.payload_powershell_file, "r") as f:
                powershell = f.read()
        except IOError as e:
            logger.error(
                "Error when trying to read powershell file: %(error)s",
                {"error": e})
            sys.exit(1)

        logger.info("Using payload from powershell file: %(path)s",
                    {"path": args.payload_powershell_file})

    if powershell is not None:
        payload = "powershell -EncodedCommand " + b64encode(
            powershell.encode("utf-16le")).decode()

    if payload is not None:
        if args.payload_delay is None:
            logger.error(
                "--payload-delay must be provided if a payload is provided.")
            sys.exit(1)

        if args.payload_duration is None:
            logger.error(
                "--payload-duration must be provided if a payload is provided."
            )
            sys.exit(1)

        try:
            config.payloadDelay = int(args.payload_delay)
        except ValueError:
            logger.error(
                "Invalid payload delay. Payload delay must be an integral number of milliseconds."
            )
            sys.exit(1)

        if config.payloadDelay < 0:
            logger.error("Payload delay must not be negative.")
            sys.exit(1)

        if config.payloadDelay < 1000:
            logger.warning(
                "You have provided a payload delay of less than 1 second."
                " We recommend you use a slightly longer delay to make sure it runs properly."
            )

        try:
            config.payloadDuration = int(args.payload_duration)
        except ValueError:
            logger.error(
                "Invalid payload duration. Payload duration must be an integral number of milliseconds."
            )
            sys.exit(1)

        if config.payloadDuration < 0:
            logger.error("Payload duration must not be negative.")
            sys.exit(1)

        config.payload = payload
    elif args.payload_delay is not None:
        logger.error("--payload-delay was provided but no payload was set.")
        sys.exit(1)

    # Configure allowed authentication protocols.
    for auth in args.auth.split(','):
        auth = auth.strip()
        if auth == "tls":
            config.authMethods |= NegotiationProtocols.SSL
        elif auth == "ssp":
            # CredSSP implies TLS.
            config.authMethods |= (NegotiationProtocols.SSL
                                   | NegotiationProtocols.CRED_SSP)

    showConfiguration(config)
    return config
コード例 #2
0
ファイル: cli.py プロジェクト: matthooper1/pyrdp
def configure(cmdline=None) -> MITMConfig:
    parser = buildArgParser()

    if cmdline:
        args = parser.parse_args(cmdline)
    else:
        args = parser.parse_args()

    # Load configuration file.
    cfg = settings.load(settings.CONFIG_DIR + '/mitm.ini', DEFAULTS)

    # Override some of the switches based on command line arguments.
    if args.output:
        cfg.set('vars', 'output_dir', args.output)
    if args.log_filter:
        cfg.set('logs', 'filter', args.log_filter)
    if args.log_level:
        cfg.set('vars', 'level', args.log_level)

    configureLoggers(cfg)
    logger = logging.getLogger(LOGGER_NAMES.PYRDP)

    outDir = Path(cfg.get('vars', 'output_dir'))
    outDir.mkdir(exist_ok=True)

    targetHost, targetPort = parseTarget(args.target)
    key, certificate = validateKeyAndCertificate(args.private_key,
                                                 args.certificate)

    config = MITMConfig()
    config.targetHost = targetHost
    config.targetPort = targetPort
    config.privateKeyFileName = key
    config.listenPort = int(args.listen)
    config.certificateFileName = certificate
    config.attackerHost = args.destination_ip
    config.attackerPort = int(args.destination_port)
    config.replacementUsername = args.username
    config.replacementPassword = args.password
    config.outDir = outDir
    config.enableCrawler = args.crawl
    config.crawlerMatchFileName = args.crawler_match_file
    config.crawlerIgnoreFileName = args.crawler_ignore_file
    config.recordReplays = not args.no_replay
    config.downgrade = not args.no_downgrade
    config.transparent = args.transparent
    config.extractFiles = not args.no_files
    config.disableActiveClipboardStealing = args.disable_active_clipboard

    payload = None
    powershell = None

    if int(args.payload is not None) + int(
            args.payload_powershell is not None) + int(
                args.payload_powershell_file is not None) > 1:
        logger.error(
            "Only one of --payload, --payload-powershell and --payload-powershell-file may be supplied."
        )
        sys.exit(1)

    if args.payload is not None:
        payload = args.payload
        logger.info("Using payload: %(payload)s", {"payload": args.payload})
    elif args.payload_powershell is not None:
        powershell = args.payload_powershell
        logger.info("Using powershell payload: %(payload)s",
                    {"payload": args.payload_powershell})
    elif args.payload_powershell_file is not None:
        if not os.path.exists(args.payload_powershell_file):
            logger.error("Powershell file %(path)s does not exist.",
                         {"path": args.payload_powershell_file})
            sys.exit(1)

        try:
            with open(args.payload_powershell_file, "r") as f:
                powershell = f.read()
        except IOError as e:
            logger.error(
                "Error when trying to read powershell file: %(error)s",
                {"error": e})
            sys.exit(1)

        logger.info("Using payload from powershell file: %(path)s",
                    {"path": args.payload_powershell_file})

    if powershell is not None:
        payload = "powershell -EncodedCommand " + b64encode(
            powershell.encode("utf-16le")).decode()

    if payload is not None:
        if args.payload_delay is None:
            logger.error(
                "--payload-delay must be provided if a payload is provided.")
            sys.exit(1)

        if args.payload_duration is None:
            logger.error(
                "--payload-duration must be provided if a payload is provided."
            )
            sys.exit(1)

        try:
            config.payloadDelay = int(args.payload_delay)
        except ValueError:
            logger.error(
                "Invalid payload delay. Payload delay must be an integral number of milliseconds."
            )
            sys.exit(1)

        if config.payloadDelay < 0:
            logger.error("Payload delay must not be negative.")
            sys.exit(1)

        if config.payloadDelay < 1000:
            logger.warning(
                "You have provided a payload delay of less than 1 second. We recommend you use a slightly longer delay to make sure it runs properly."
            )

        try:
            config.payloadDuration = int(args.payload_duration)
        except ValueError:
            logger.error(
                "Invalid payload duration. Payload duration must be an integral number of milliseconds."
            )
            sys.exit(1)

        if config.payloadDuration < 0:
            logger.error("Payload duration must not be negative.")
            sys.exit(1)

        config.payload = payload
    elif args.payload_delay is not None:
        logger.error("--payload-delay was provided but no payload was set.")
        sys.exit(1)

    showConfiguration(config)
    return config