コード例 #1
0
ファイル: scheduler.py プロジェクト: neveralso/cuckoo
    def unroute_network(self):
        """Disable any enabled network routing."""
        cfg = self.routing_cfg

        if self.interface:
            rooter(
                "forward_disable", self.machine.interface,
                self.interface, self.machine.ip
            )

        if self.rt_table:
            rooter(
                "srcroute_disable", self.rt_table, self.machine.ip
            )

        if self.route != "none":
            rooter(
                "drop_disable", self.machine.ip,
                config("cuckoo:resultserver:ip"),
                str(config("cuckoo:resultserver:port"))
            )

        if self.route == "inetsim":
            rooter("inetsim_disable", self.machine.ip,
                   cfg.inetsim.server,
                   str(cfg.resultserver.port))

        if self.route == "tor":
            rooter(
                "tor_disable", self.machine.ip,
                str(config("cuckoo:resultserver:ip")),
                str(config("routing:tor:dnsport")),
                str(config("routing:tor:proxyport"))
            )
コード例 #2
0
ファイル: replay.py プロジェクト: CERT-Polska/cuckoo
    def stop(self):
        machinery = config("cuckoo:cuckoo:machinery")
        self.port and rooter(
            "inetsim_disable", self.machine.ip,
            config("cuckoo:resultserver:ip"),
            config("%s:%s:interface" % (machinery, machinery)),
            str(config("cuckoo:resultserver:port")),
            "80:%d 443:%d" % (self.port, self.port)
        )

        if self.proc and not self.proc.poll():
            try:
                self.proc.terminate()
                PORTS.remove(self.port)
            except:
                try:
                    if not self.proc.poll():
                        log.debug("Killing mitmdump")
                        self.proc.kill()
                        PORTS.remove(self.port)
                except OSError as e:
                    log.debug("Error killing mitmdump: %s. Continue", e)
                except Exception as e:
                    log.exception("Unable to stop mitmdump with pid %d: %s",
                                  self.proc.pid, e)
コード例 #3
0
ファイル: test_rooter.py プロジェクト: LetMeR00t/cuckoo
def test_rooter_client(p, q, r):
    set_cwd(tempfile.mkdtemp())
    cuckoo_create()

    s = p.socket.return_value
    s.recv.return_value = json.dumps({
        "exception": None,
        "output": "thisisoutput",
    })
    assert rooter(
        "command", "arg1", "arg2", arg3="foo", arg4="bar"
    ) == "thisisoutput"

    s.bind.assert_called_once()
    s.connect.assert_called_once_with("/tmp/cuckoo-rooter")
    s.send.assert_called_once_with(json.dumps({
        "command": "command",
        "args": (
            "arg1",
            "arg2",
        ),
        "kwargs": {
            "arg3": "foo",
            "arg4": "bar",
        }
    }))
    q.acquire.assert_called_once()
    q.release.assert_called_once()
コード例 #4
0
ファイル: scheduler.py プロジェクト: CERT-Polska/cuckoo
    def unroute_network(self):
        """Disable any enabled network routing."""
        if self.interface:
            rooter(
                "forward_disable", self.machine.interface,
                self.interface, self.machine.ip
            )

        if self.rt_table:
            rooter(
                "srcroute_disable", self.rt_table, self.machine.ip
            )

        if self.route == "drop" or self.route == "internet":
            rooter(
                "drop_disable", self.machine.ip,
                config("cuckoo:resultserver:ip"),
                str(config("cuckoo:resultserver:port"))
            )

        if self.route == "inetsim":
            machinery = config("cuckoo:cuckoo:machinery")
            rooter(
                "inetsim_disable", self.machine.ip,
                config("routing:inetsim:server"),
                config("%s:%s:interface" % (machinery, machinery)),
                str(config("cuckoo:resultserver:port")),
                config("routing:inetsim:ports") or ""
            )

        if self.route == "tor":
            rooter(
                "tor_disable", self.machine.ip,
                str(config("cuckoo:resultserver:ip")),
                str(config("routing:tor:dnsport")),
                str(config("routing:tor:proxyport"))
            )
コード例 #5
0
ファイル: startup.py プロジェクト: ptcNOP/cuckoo
def init_rooter():
    """If required, check if the rooter is running and if we can connect
    to it. The default configuration doesn't require the rooter to be ran."""
    required = (
        config("routing:routing:route") != "none" or
        config("routing:routing:internet") != "none" or
        config("routing:routing:drop") or
        config("routing:inetsim:enabled") or
        config("routing:tor:enabled") or
        config("routing:vpn:enabled")
    )
    if not required:
        return

    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)

    try:
        s.connect(config("cuckoo:cuckoo:rooter"))
    except socket.error as e:
        if e.strerror == "No such file or directory":
            raise CuckooStartupError(
                "The rooter is required but it is either not running or it "
                "has been configured to a different Unix socket path. Please "
                "refer to the documentation on working with the rooter."
            )

        if e.strerror == "Connection refused":
            raise CuckooStartupError(
                "The rooter is required but we can't connect to it as the "
                "rooter is not actually running. Please refer to the "
                "documentation on working with the rooter."
            )

        if e.strerror == "Permission denied":
            raise CuckooStartupError(
                "The rooter is required but we can't connect to it due to "
                "incorrect permissions. Did you assign it the correct group? "
                "Please refer to the documentation on working with the "
                "rooter."
            )

        raise CuckooStartupError("Unknown rooter error: %s" % e)

    # Do not forward any packets unless we have explicitly stated so.
    rooter("forward_drop")

    # Enable stateful connection tracking (but only once).
    rooter("state_disable")
    rooter("state_enable")
コード例 #6
0
ファイル: replay.py プロジェクト: CERT-Polska/cuckoo
    def start(self):
        # Have to explicitly enable Replay.
        if not self.task.options.get("replay"):
            return

        if self.task.options.get("route"):
            log.error(
                "A network route must not be specified when performing a "
                "Replay analysis."
            )
            return

        # TODO We have to do version checking on mitmdump.
        mitmdump = self.options["mitmdump"]
        port_base = self.options["port_base"]
        certificate = self.options["certificate"]

        cert_path = cwd("analyzer", "windows", certificate)
        if not os.path.exists(cert_path):
            log.error("Mitmdump root certificate not found at path \"%s\" "
                      "(real path \"%s\"), man in the middle interception "
                      "aborted.", certificate, cert_path)
            return

        mitmpath = self.task.options["replay"]
        if not mitmpath.endswith((".pcap", ".mitm")):
            log.error(
                "Invalid filename (should end with .pcap or .mitm): %s. "
                "Can't proceed with replay analysis.", mitmpath
            )
            return

        # We support both .mitm and .pcap files.
        if mitmpath.endswith(".pcap"):
            tlsmaster = self.task.options.get("replay.tls")
            mitmpath = self.pcap2mitm(mitmpath, tlsmaster)

        if not os.path.getsize(mitmpath):
            log.error(
                "Empty .mitm file (potentially after conversion from .pcap), "
                "do you have the mitmproxy version 0.18.2 installed (in the "
                "same environment as Cuckoo)?"
            )
            log.info("Aborting Replay capabilities.")
            return

        PORT_LOCK.acquire()

        for port in xrange(port_base, port_base + 512):
            if port not in PORTS:
                self.port = port
                break

        PORTS.append(self.port)

        PORT_LOCK.release()

        # TODO Better access to self.machine and its related fields.
        machinery = config("cuckoo:cuckoo:machinery")
        rooter(
            "inetsim_enable", self.machine.ip,
            config("cuckoo:resultserver:ip"),
            config("%s:%s:interface" % (machinery, machinery)),
            str(config("cuckoo:resultserver:port")),
            "80:%d 443:%d" % (self.port, self.port)
        )

        args = [
            mitmdump, "-S", mitmpath,
            "--set", "server_replay_ignore_content",
            "--set", "server_replay_ignore_host",
            # With the port redirection provided by our InetSim support,
            # server_replay_ignore_port is strictly speaking irrelevant.
            # "--set", "server_replay_ignore_port",
            "--server-replay-kill-extra",
            "--mode", "transparent",
            "-k", "-q", "-p", "%d" % self.port,
        ]

        self.proc = Popen(args, close_fds=True)

        if "cert" in self.task.options:
            log.warning("A root certificate has been provided for this task, "
                        "however, this is overridden by the mitm auxiliary "
                        "module.")

        self.task.options["cert"] = certificate

        log.info(
            "Started PCAP replay PID %d (ip=%s, port=%d).",
            self.proc.pid, self.machine.resultserver_ip, self.port
        )
コード例 #7
0
ファイル: vpncheck.py プロジェクト: iNarcissuss/Cuckoodroid-1
                        default="/tmp/cuckoo-vpncheck",
                        help="Unix socket path of this client")
    parser.add_argument("-v",
                        "--verbose",
                        action="store_true",
                        help="Enable verbose logging")
    args = parser.parse_args()

    if os.path.exists(args.client):
        os.unlink(args.client)

    init_rooter()
    init_routing()

    error = 0
    for vpn, status in rooter("vpn_status").items():
        if vpn not in vpns:
            print "Not a configured VPN", vpn
            continue

        if not rooter("nic_available", vpns[vpn].interface):
            print >> sys.stderr, "VPN is no longer available", vpn
            error = 1
            continue

        ipaddr = get_ip_address(vpns[vpn].interface)

        rooter("forward_enable", vpns[vpn].interface, vpns[vpn].interface,
               ipaddr)
        rooter("srcroute_enable", vpns[vpn].rt_table, ipaddr)
コード例 #8
0
ファイル: api.py プロジェクト: CERT-Polska/cuckoo
def vpn_status():
    status = rooter("vpn_status")
    if status is None:
        return json_error(500, "Rooter not available")

    return jsonify({"vpns": status})
コード例 #9
0
ファイル: scheduler.py プロジェクト: weloveit/mycuckoo
    def route_network(self):
        """Enable network routing if desired."""
        # Determine the desired routing strategy (none, internet, VPN).
        self.route = self.task.options.get("route",
                                           config("routing:routing:route"))

        if self.route == "none" or self.route == "drop":
            self.interface = None
            self.rt_table = None
        elif self.route == "inetsim":
            pass
        elif self.route == "tor":
            pass
        elif self.route == "internet":
            if config("routing:routing:internet") == "none":
                log.warning(
                    "Internet network routing has been specified, but not "
                    "configured, ignoring routing for this analysis",
                    extra={
                        "action": "network.route",
                        "status": "error",
                        "route": self.route,
                    })
                self.route = "none"
                self.task.options["route"] = "none"
                self.interface = None
                self.rt_table = None
            else:
                self.interface = config("routing:routing:internet")
                self.rt_table = config("routing:routing:rt_table")
        elif self.route in config("routing:vpn:vpns"):
            self.interface = config("routing:%s:interface" % self.route)
            self.rt_table = config("routing:%s:rt_table" % self.route)
        else:
            log.warning(
                "Unknown network routing destination specified, ignoring "
                "routing for this analysis: %r",
                self.route,
                extra={
                    "action": "network.route",
                    "status": "error",
                    "route": self.route,
                })
            self.route = "none"
            self.task.options["route"] = "none"
            self.interface = None
            self.rt_table = None

        # Check if the network interface is still available. If a VPN dies for
        # some reason, its tunX interface will no longer be available.
        if self.interface and not rooter("nic_available", self.interface):
            log.error(
                "The network interface '%s' configured for this analysis is "
                "not available at the moment, switching to route=none mode.",
                self.interface,
                extra={
                    "action": "network.route",
                    "status": "error",
                    "route": self.route,
                })
            self.route = "none"
            self.task.options["route"] = "none"
            self.interface = None
            self.rt_table = None

        # For now this doesn't work yet in combination with tor routing.
        if self.route == "drop" or self.route == "internet":
            rooter("drop_enable", self.machine.ip,
                   config("cuckoo:resultserver:ip"),
                   str(config("cuckoo:resultserver:port")))

        if self.route == "inetsim":
            machinery = config("cuckoo:cuckoo:machinery")
            rooter("inetsim_enable", self.machine.ip,
                   config("routing:inetsim:server"),
                   config("%s:%s:interface" % (machinery, machinery)),
                   str(config("cuckoo:resultserver:port")),
                   config("routing:inetsim:ports") or "")

        if self.route == "tor":
            rooter("tor_enable", self.machine.ip,
                   str(config("cuckoo:resultserver:ip")),
                   str(config("routing:tor:dnsport")),
                   str(config("routing:tor:proxyport")))

        if self.interface:
            rooter("forward_enable", self.machine.interface, self.interface,
                   self.machine.ip)

        if self.rt_table:
            rooter("srcroute_enable", self.rt_table, self.machine.ip)

        # Propagate the taken route to the database.
        self.db.set_route(self.task.id, self.route)
コード例 #10
0
ファイル: scheduler.py プロジェクト: weloveit/mycuckoo
    def initialize(self):
        """Initialize the machine manager."""
        global machinery, machine_lock

        machinery_name = self.cfg.cuckoo.machinery

        max_vmstartup_count = self.cfg.cuckoo.max_vmstartup_count
        if max_vmstartup_count:
            machine_lock = threading.Semaphore(max_vmstartup_count)
        else:
            machine_lock = threading.Lock()

        log.info("Using \"%s\" as machine manager",
                 machinery_name,
                 extra={
                     "action": "init.machinery",
                     "status": "success",
                     "machinery": machinery_name,
                 })

        # Initialize the machine manager.
        machinery = cuckoo.machinery.plugins[machinery_name]()

        # Provide a dictionary with the configuration options to the
        # machine manager instance.
        machinery.set_options(Config(machinery_name))

        # Initialize the machine manager.
        try:
            machinery.initialize(machinery_name)
        except CuckooMachineError as e:
            raise CuckooCriticalError("Error initializing machines: %s" % e)

        # At this point all the available machines should have been identified
        # and added to the list. If none were found, Cuckoo aborts the
        # execution. TODO In the future we'll probably want get rid of this.
        if not machinery.machines():
            raise CuckooCriticalError("No machines available.")

        log.info("Loaded %s machine/s",
                 len(machinery.machines()),
                 extra={
                     "action": "init.machines",
                     "status": "success",
                     "count": len(machinery.machines()),
                 })

        if len(machinery.machines()) > 1 and self.db.engine.name == "sqlite":
            log.warning("As you've configured Cuckoo to execute parallel "
                        "analyses, we recommend you to switch to a MySQL or "
                        "a PostgreSQL database as SQLite might cause some "
                        "issues.")

        if len(machinery.machines()) > 4 and self.cfg.cuckoo.process_results:
            log.warning("When running many virtual machines it is recommended "
                        "to process the results in separate 'cuckoo process' "
                        "instances to increase throughput and stability. "
                        "Please read the documentation about the "
                        "`Processing Utility`.")

        # Drop all existing packet forwarding rules for each VM. Just in case
        # Cuckoo was terminated for some reason and various forwarding rules
        # have thus not been dropped yet.
        for machine in machinery.machines():
            if not machine.interface:
                log.info(
                    "Unable to determine the network interface for VM "
                    "with name %s, Cuckoo will not be able to give it "
                    "full internet access or route it through a VPN! "
                    "Please define a default network interface for the "
                    "machinery or define a network interface for each "
                    "VM.", machine.name)
                continue

            # Drop forwarding rule to each VPN.
            if config("routing:vpn:enabled"):
                for vpn in config("routing:vpn:vpns"):
                    rooter("forward_disable", machine.interface,
                           config("routing:%s:interface" % vpn), machine.ip)

            # Drop forwarding rule to the internet / dirty line.
            if config("routing:routing:internet") != "none":
                rooter("forward_disable", machine.interface,
                       config("routing:routing:internet"), machine.ip)
コード例 #11
0
ファイル: scheduler.py プロジェクト: CERT-Polska/cuckoo
    def initialize(self):
        """Initialize the machine manager."""
        global machinery, machine_lock

        machinery_name = self.cfg.cuckoo.machinery

        max_vmstartup_count = self.cfg.cuckoo.max_vmstartup_count
        if max_vmstartup_count:
            machine_lock = threading.Semaphore(max_vmstartup_count)
        else:
            machine_lock = threading.Lock()

        log.info("Using \"%s\" as machine manager", machinery_name, extra={
            "action": "init.machinery",
            "status": "success",
            "machinery": machinery_name,
        })

        # Initialize the machine manager.
        machinery = cuckoo.machinery.plugins[machinery_name]()

        # Provide a dictionary with the configuration options to the
        # machine manager instance.
        machinery.set_options(Config(machinery_name))

        # Initialize the machine manager.
        try:
            machinery.initialize(machinery_name)
        except CuckooMachineError as e:
            raise CuckooCriticalError("Error initializing machines: %s" % e)

        # At this point all the available machines should have been identified
        # and added to the list. If none were found, Cuckoo aborts the
        # execution. TODO In the future we'll probably want get rid of this.
        if not machinery.machines():
            raise CuckooCriticalError("No machines available.")

        log.info("Loaded %s machine/s", len(machinery.machines()), extra={
            "action": "init.machines",
            "status": "success",
            "count": len(machinery.machines()),
        })

        if len(machinery.machines()) > 1 and self.db.engine.name == "sqlite":
            log.warning("As you've configured Cuckoo to execute parallel "
                        "analyses, we recommend you to switch to a MySQL or "
                        "a PostgreSQL database as SQLite might cause some "
                        "issues.")

        if len(machinery.machines()) > 4 and self.cfg.cuckoo.process_results:
            log.warning("When running many virtual machines it is recommended "
                        "to process the results in separate 'cuckoo process' "
                        "instances to increase throughput and stability. "
                        "Please read the documentation about the "
                        "`Processing Utility`.")

        # Drop all existing packet forwarding rules for each VM. Just in case
        # Cuckoo was terminated for some reason and various forwarding rules
        # have thus not been dropped yet.
        for machine in machinery.machines():
            if not machine.interface:
                log.info("Unable to determine the network interface for VM "
                         "with name %s, Cuckoo will not be able to give it "
                         "full internet access or route it through a VPN! "
                         "Please define a default network interface for the "
                         "machinery or define a network interface for each "
                         "VM.", machine.name)
                continue

            # Drop forwarding rule to each VPN.
            if config("routing:vpn:enabled"):
                for vpn in config("routing:vpn:vpns"):
                    rooter(
                        "forward_disable", machine.interface,
                        config("routing:%s:interface" % vpn), machine.ip
                    )

            # Drop forwarding rule to the internet / dirty line.
            if config("routing:routing:internet") != "none":
                rooter(
                    "forward_disable", machine.interface,
                    config("routing:routing:internet"), machine.ip
                )
コード例 #12
0
ファイル: startup.py プロジェクト: ptcNOP/cuckoo
def init_routing():
    """Initialize and check whether the routing information is correct."""
    interfaces = set()

    # Check if all configured VPNs exist and are up and enable NAT on
    # each VPN interface.
    if config("routing:vpn:enabled"):
        for name in config("routing:vpn:vpns"):
            entry = config2("routing", name)
            if not rooter("nic_available", entry.interface):
                raise CuckooStartupError(
                    "The network interface that has been configured for "
                    "VPN %s is not available." % entry.name
                )

            if not rooter("rt_available", entry.rt_table):
                raise CuckooStartupError(
                    "The routing table that has been configured for "
                    "VPN %s is not available." % entry.name
                )

            interfaces.add((entry.rt_table, entry.interface))

    standard_routes = "none", "drop", "internet", "inetsim", "tor"

    # Check whether the default VPN exists if specified.
    if config("routing:routing:route") not in standard_routes:
        if config("routing:routing:route") not in config("routing:vpn:vpns"):
            raise CuckooStartupError(
                "The default routing target (%s) has not been configured in "
                "routing.conf, is it supposed to be a VPN?" %
                config("routing:routing:route")
            )

        if not config("routing:vpn:enabled"):
            raise CuckooStartupError(
                "The default route configured is a VPN, but VPNs have "
                "not been enabled in routing.conf."
            )

    # Check whether the dirty line exists if it has been defined.
    if config("routing:routing:internet") != "none":
        if not rooter("nic_available", config("routing:routing:internet")):
            raise CuckooStartupError(
                "The network interface that has been configured as dirty "
                "line is not available."
            )

        if not rooter("rt_available", config("routing:routing:rt_table")):
            raise CuckooStartupError(
                "The routing table that has been configured for dirty "
                "line interface is not available."
            )

        interfaces.add((
            config("routing:routing:rt_table"),
            config("routing:routing:internet")
        ))

    for rt_table, interface in interfaces:
        # Disable & enable NAT on this network interface. Disable it just
        # in case we still had the same rule from a previous run.
        rooter("disable_nat", interface)
        rooter("enable_nat", interface)

        # Populate routing table with entries from main routing table.
        if config("routing:routing:auto_rt"):
            rooter("flush_rttable", rt_table)
            rooter("init_rttable", rt_table, interface)
コード例 #13
0
ファイル: scheduler.py プロジェクト: CERT-Polska/cuckoo
    def route_network(self):
        """Enable network routing if desired."""
        # Determine the desired routing strategy (none, internet, VPN).
        self.route = self.task.options.get(
            "route", config("routing:routing:route")
        )

        if self.route == "none" or self.route == "drop":
            self.interface = None
            self.rt_table = None
        elif self.route == "inetsim":
            pass
        elif self.route == "tor":
            pass
        elif self.route == "internet":
            if config("routing:routing:internet") == "none":
                log.warning(
                    "Internet network routing has been specified, but not "
                    "configured, ignoring routing for this analysis", extra={
                        "action": "network.route",
                        "status": "error",
                        "route": self.route,
                    }
                )
                self.route = "none"
                self.task.options["route"] = "none"
                self.interface = None
                self.rt_table = None
            else:
                self.interface = config("routing:routing:internet")
                self.rt_table = config("routing:routing:rt_table")
        elif self.route in config("routing:vpn:vpns"):
            self.interface = config("routing:%s:interface" % self.route)
            self.rt_table = config("routing:%s:rt_table" % self.route)
        else:
            log.warning(
                "Unknown network routing destination specified, ignoring "
                "routing for this analysis: %r", self.route, extra={
                    "action": "network.route",
                    "status": "error",
                    "route": self.route,
                }
            )
            self.route = "none"
            self.task.options["route"] = "none"
            self.interface = None
            self.rt_table = None

        # Check if the network interface is still available. If a VPN dies for
        # some reason, its tunX interface will no longer be available.
        if self.interface and not rooter("nic_available", self.interface):
            log.error(
                "The network interface '%s' configured for this analysis is "
                "not available at the moment, switching to route=none mode.",
                self.interface, extra={
                    "action": "network.route",
                    "status": "error",
                    "route": self.route,
                }
            )
            self.route = "none"
            self.task.options["route"] = "none"
            self.interface = None
            self.rt_table = None

        # For now this doesn't work yet in combination with tor routing.
        if self.route == "drop" or self.route == "internet":
            rooter(
                "drop_enable", self.machine.ip,
                config("cuckoo:resultserver:ip"),
                str(config("cuckoo:resultserver:port"))
            )

        if self.route == "inetsim":
            machinery = config("cuckoo:cuckoo:machinery")
            rooter(
                "inetsim_enable", self.machine.ip,
                config("routing:inetsim:server"),
                config("%s:%s:interface" % (machinery, machinery)),
                str(config("cuckoo:resultserver:port")),
                config("routing:inetsim:ports") or ""
            )

        if self.route == "tor":
            rooter(
                "tor_enable", self.machine.ip,
                str(config("cuckoo:resultserver:ip")),
                str(config("routing:tor:dnsport")),
                str(config("routing:tor:proxyport"))
            )

        if self.interface:
            rooter(
                "forward_enable", self.machine.interface,
                self.interface, self.machine.ip
            )

        if self.rt_table:
            rooter(
                "srcroute_enable", self.rt_table, self.machine.ip
            )

        # Propagate the taken route to the database.
        self.db.set_route(self.task.id, self.route)
コード例 #14
0
def vpn_status():
    status = rooter("vpn_status")
    if status is None:
        return json_error(500, "Rooter not available")

    return jsonify({"vpns": status})
コード例 #15
0
ファイル: api.py プロジェクト: MAECProject/cuckoo
    def vpn_status(request):
        status = rooter("vpn_status")
        if status is None:
            return json_fatal_response("Rooter not available")

        return JsonResponse({"status": True, "vpns": status})
コード例 #16
0
    def vpn_status(request):
        status = rooter("vpn_status")
        if status is None:
            return json_fatal_response("Rooter not available")

        return JsonResponse({"status": True, "vpns": status})
コード例 #17
0
    def start(self):
        # Have to explicitly enable Replay.
        if not self.task.options.get("replay"):
            return

        if self.task.options.get("route"):
            log.error(
                "A network route must not be specified when performing a "
                "Replay analysis."
            )
            return

        # TODO We have to do version checking on mitmdump.
        mitmdump = self.options["mitmdump"]
        port_base = self.options["port_base"]
        certificate = self.options["certificate"]

        cert_path = cwd("analyzer", "windows", certificate)
        if not os.path.exists(cert_path):
            log.error("Mitmdump root certificate not found at path \"%s\" "
                      "(real path \"%s\"), man in the middle interception "
                      "aborted.", certificate, cert_path)
            return

        mitmpath = self.task.options["replay"]
        if not mitmpath.endswith((".pcap", ".mitm")):
            log.error(
                "Invalid filename (should end with .pcap or .mitm): %s. "
                "Can't proceed with replay analysis.", mitmpath
            )
            return

        # We support both .mitm and .pcap files.
        if mitmpath.endswith(".pcap"):
            tlsmaster = self.task.options.get("replay.tls")
            mitmpath = self.pcap2mitm(mitmpath, tlsmaster)

        if not os.path.getsize(mitmpath):
            log.error(
                "Empty .mitm file (potentially after conversion from .pcap), "
                "do you have the mitmproxy version 0.18.2 installed (in the "
                "same environment as Cuckoo)?"
            )
            log.info("Aborting Replay capabilities.")
            return

        PORT_LOCK.acquire()

        for port in xrange(port_base, port_base + 512):
            if port not in PORTS:
                self.port = port
                break

        PORTS.append(self.port)

        PORT_LOCK.release()

        # TODO Better access to self.machine and its related fields.
        machinery = config("cuckoo:cuckoo:machinery")
        rooter(
            "inetsim_enable", self.machine.ip,
            config("cuckoo:resultserver:ip"),
            config("%s:%s:interface" % (machinery, machinery)),
            str(config("cuckoo:resultserver:port")),
            "80:%d 443:%d" % (self.port, self.port)
        )

        args = [
            mitmdump, "-S", mitmpath,
            "--set", "server_replay_ignore_content",
            "--set", "server_replay_ignore_host",
            # With the port redirection provided by our InetSim support,
            # server_replay_ignore_port is strictly speaking irrelevant.
            # "--set", "server_replay_ignore_port",
            "--server-replay-kill-extra",
            "--mode", "transparent",
            "-k", "-q", "-p", "%d" % self.port,
        ]

        self.proc = Popen(args, close_fds=True)

        if "cert" in self.task.options:
            log.warning("A root certificate has been provided for this task, "
                        "however, this is overridden by the mitm auxiliary "
                        "module.")

        self.task.options["cert"] = certificate

        log.info(
            "Started PCAP replay PID %d (ip=%s, port=%d).",
            self.proc.pid, self.machine.resultserver_ip, self.port
        )
コード例 #18
0
ファイル: startup.py プロジェクト: hatching/cuckoo-ekhunting
def init_routing():
    """Initialize and check whether the routing information is correct."""
    interfaces = set()

    # Check if all configured VPNs exist and are up and enable NAT on
    # each VPN interface.
    if config("routing:vpn:enabled"):
        for name in config("routing:vpn:vpns"):
            entry = config2("routing", name)
            if not rooter("nic_available", entry.interface):
                raise CuckooStartupError(
                    "The network interface that has been configured for "
                    "VPN %s is not available." % entry.name)

            if not rooter("rt_available", entry.rt_table):
                raise CuckooStartupError(
                    "The routing table that has been configured for "
                    "VPN %s is not available." % entry.name)

            interfaces.add((entry.rt_table, entry.interface))

        VPNManager.init()

    standard_routes = "none", "drop", "internet", "inetsim", "tor"

    # Check whether the default VPN exists if specified.
    if config("routing:routing:route") not in standard_routes:
        if config("routing:routing:route") not in config("routing:vpn:vpns"):
            raise CuckooStartupError(
                "The default routing target (%s) has not been configured in "
                "routing.conf, is it supposed to be a VPN?" %
                config("routing:routing:route"))

        if not config("routing:vpn:enabled"):
            raise CuckooStartupError(
                "The default route configured is a VPN, but VPNs have "
                "not been enabled in routing.conf.")

    # Check whether the dirty line exists if it has been defined.
    if config("routing:routing:internet") != "none":
        if not rooter("nic_available", config("routing:routing:internet")):
            raise CuckooStartupError(
                "The network interface that has been configured as dirty "
                "line is not available.")

        if not rooter("rt_available", config("routing:routing:rt_table")):
            raise CuckooStartupError(
                "The routing table that has been configured for dirty "
                "line interface is not available.")

        interfaces.add((config("routing:routing:rt_table"),
                        config("routing:routing:internet")))

    for rt_table, interface in interfaces:
        # Disable & enable NAT on this network interface. Disable it just
        # in case we still had the same rule from a previous run.
        rooter("disable_nat", interface)
        rooter("enable_nat", interface)

        # Populate routing table with entries from main routing table.
        if config("routing:routing:auto_rt"):
            rooter("flush_rttable", rt_table)
            rooter("init_rttable", rt_table, interface)