Example #1
0
    def start_mitmproxy_playback(self, mitmdump_path, browser_path):
        """Startup mitmproxy and replay the specified flow file"""
        if self.mitmproxy_proc is not None:
            raise Exception("Proxy already started.")
        self.port = get_available_port()
        LOG.info("mitmdump path: %s" % mitmdump_path)
        LOG.info("browser path: %s" % browser_path)

        # mitmproxy needs some DLL's that are a part of Firefox itself, so add to path
        env = os.environ.copy()
        env["PATH"] = os.path.dirname(browser_path) + os.pathsep + env["PATH"]
        command = [mitmdump_path]

        # add proxy host and port options
        command.extend(
            ["--listen-host", self.host, "--listen-port",
             str(self.port)])

        if "playback_tool_args" in self.config:
            LOG.info("Staring Proxy using provided command line!")
            command.extend(self.config["playback_tool_args"])
        elif "playback_files" in self.config:
            script = os.path.join(
                os.path.dirname(os.path.realpath(__file__)),
                "scripts",
                "alternate-server-replay.py",
            )
            self.recording_paths = [
                normalize_path(recording_path)
                for recording_path in self.config["playback_files"]
            ]

            if self.config["playback_version"] in ["4.0.4", "5.0.1"]:
                args = [
                    "-v",
                    "--set",
                    "upstream_cert=false",
                    "--set",
                    "upload_dir=" + normalize_path(self.upload_dir),
                    "--set",
                    "websocket=false",
                    "--set",
                    "server_replay_files={}".format(",".join(
                        self.recording_paths)),
                    "--scripts",
                    normalize_path(script),
                ]
                command.extend(args)
            else:
                raise Exception("Mitmproxy version is unknown!")

        else:
            raise Exception(
                "Mitmproxy can't start playback! Playback settings missing.")

        LOG.info("Starting mitmproxy playback using env path: %s" %
                 env["PATH"])
        LOG.info("Starting mitmproxy playback using command: %s" %
                 " ".join(command))
        # to turn off mitmproxy log output, use these params for Popen:
        # Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        self.mitmproxy_proc = ProcessHandler(
            command,
            logfile=os.path.join(self.upload_dir, "mitmproxy.log"),
            env=env,
            processStderrLine=LOG.error,
            storeOutput=False,
        )
        self.mitmproxy_proc.run()
        end_time = time.time() + MITMDUMP_COMMAND_TIMEOUT
        ready = False
        while time.time() < end_time:
            ready = self.check_proxy(host=self.host, port=self.port)
            if ready:
                LOG.info(
                    "Mitmproxy playback successfully started on %s:%d as pid %d"
                    % (self.host, self.port, self.mitmproxy_proc.pid))
                return
            time.sleep(0.25)
        # cannot continue as we won't be able to playback the pages
        LOG.error("Aborting: Mitmproxy process did not startup")
        self.stop_mitmproxy_playback()
        sys.exit()  # XXX why do we need to do that? a raise is not enough?
Example #2
0
    def start_mitmproxy(self, mitmdump_path, browser_path):
        """Startup mitmproxy and replay the specified flow file"""
        if self.mitmproxy_proc is not None:
            raise Exception("Proxy already started.")
        self.port = get_available_port()

        LOG.info("mitmdump path: %s" % mitmdump_path)
        LOG.info("browser path: %s" % browser_path)

        # mitmproxy needs some DLL's that are a part of Firefox itself, so add to path
        env = os.environ.copy()
        env["PATH"] = os.path.dirname(browser_path) + os.pathsep + env["PATH"]
        command = [mitmdump_path]

        if self.config.get("verbose", False):
            # Generate mitmproxy verbose logs
            command.extend(["-v"])
        # add proxy host and port options
        command.extend(
            ["--listen-host", self.host, "--listen-port",
             str(self.port)])

        # record mode
        if self.record_mode:

            # generate recording script paths
            inject_deterministic = os.path.join(
                mitm_folder,
                "scripts",
                "inject-deterministic.py",
            )
            http_protocol_extractor = os.path.join(
                mitm_folder,
                "scripts",
                "http_protocol_extractor.py",
            )

            args = [
                "--save-stream-file",
                normalize_path(self.recording.recording_path),
                "--set",
                "websocket=false",
                "--scripts",
                inject_deterministic,
                "--scripts",
                http_protocol_extractor,
            ]
            command.extend(args)
            self.recording.set_metadata("proxy_version",
                                        self.config["playback_version"])
        else:
            # playback mode
            if len(self.playback_files) > 0:
                script = os.path.join(
                    mitm_folder,
                    "scripts",
                    "alternate-server-replay.py",
                )

                if self.config["playback_version"] in [
                        "4.0.4", "5.1.1", "6.0.2"
                ]:
                    args = [
                        "--set",
                        "upstream_cert=false",
                        "--set",
                        "upload_dir=" + normalize_path(self.upload_dir),
                        "--set",
                        "websocket=false",
                        "--set",
                        "server_replay_files={}".format(",".join([
                            normalize_path(playback_file.recording_path)
                            for playback_file in self.playback_files
                        ])),
                        "--scripts",
                        normalize_path(script),
                    ]
                    command.extend(args)
                else:
                    raise Exception("Mitmproxy version is unknown!")

            else:
                raise Exception(
                    "Mitmproxy can't start playback! Playback settings missing."
                )

        # mitmproxy needs some DLL's that are a part of Firefox itself, so add to path
        env = os.environ.copy()
        if not os.path.dirname(self.browser_path) in env["PATH"]:
            env["PATH"] = os.path.dirname(
                self.browser_path) + os.pathsep + env["PATH"]

        LOG.info("Starting mitmproxy playback using env path: %s" %
                 env["PATH"])
        LOG.info("Starting mitmproxy playback using command: %s" %
                 " ".join(command))
        # to turn off mitmproxy log output, use these params for Popen:
        # Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        self.mitmproxy_proc = ProcessHandler(
            command,
            logfile=os.path.join(self.upload_dir, "mitmproxy.log"),
            env=env,
            processStderrLine=LOG.error,
            storeOutput=False,
        )
        self.mitmproxy_proc.run()
        end_time = time.time() + MITMDUMP_COMMAND_TIMEOUT

        ready = False
        while time.time() < end_time:
            ready = self.check_proxy(host=self.host, port=self.port)
            if ready:
                LOG.info(
                    "Mitmproxy playback successfully started on %s:%d as pid %d"
                    % (self.host, self.port, self.mitmproxy_proc.pid))
                return
            time.sleep(0.25)

        # cannot continue as we won't be able to playback the pages
        LOG.error("Aborting: Mitmproxy process did not startup")
        self.stop_mitmproxy_playback()
        sys.exit(1)  # XXX why do we need to do that? a raise is not enough?