#2689 Implemented initial agent actions and started on documentations. A few TODO's left to do such as validation and expanding unit tests.
This commit is contained in:
@@ -213,7 +213,7 @@ class AbstractC2(Application, identifier="AbstractC2"):
|
||||
return True
|
||||
else:
|
||||
self.sys_log.warning(
|
||||
f"{self.name}: failed to send a Keep Alive. The node may be unable to access the ``network."
|
||||
f"{self.name}: failed to send a Keep Alive. The node may be unable to access networking resources."
|
||||
)
|
||||
return False
|
||||
|
||||
@@ -251,7 +251,7 @@ class AbstractC2(Application, identifier="AbstractC2"):
|
||||
# This statement is intended to catch on the C2 Application that is listening for connection. (C2 Beacon)
|
||||
if self.c2_remote_connection is None:
|
||||
self.sys_log.debug(f"{self.name}: Attempting to configure remote C2 connection based off received output.")
|
||||
self.c2_remote_connection = self.current_c2_session.with_ip_address
|
||||
self.c2_remote_connection = IPv4Address(self.current_c2_session.with_ip_address)
|
||||
|
||||
self.c2_connection_active = True # Sets the connection to active
|
||||
self.keep_alive_inactivity = 0 # Sets the keep alive inactivity to zero
|
||||
|
||||
@@ -13,6 +13,7 @@ from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
from primaite.simulator.network.transmission.transport_layer import Port
|
||||
from primaite.simulator.system.applications.application import ApplicationOperatingState
|
||||
from primaite.simulator.system.applications.red_applications.c2.abstract_c2 import AbstractC2, C2Command, C2Payload
|
||||
from primaite.simulator.system.applications.red_applications.ransomware_script import RansomwareScript
|
||||
from primaite.simulator.system.software import SoftwareHealthState
|
||||
|
||||
|
||||
@@ -44,8 +45,6 @@ class C2Beacon(AbstractC2, identifier="C2 Beacon"):
|
||||
|
||||
# TODO:
|
||||
# Implement the placeholder command methods
|
||||
# Implement the keep alive frequency.
|
||||
# Implement a command output method that sends the RequestResponse to the C2 server.
|
||||
# Uncomment the terminal Import and the terminal property after terminal PR
|
||||
|
||||
# @property
|
||||
@@ -56,6 +55,14 @@ class C2Beacon(AbstractC2, identifier="C2 Beacon"):
|
||||
# self.sys_log.warning(f"{self.__class__.__name__} cannot find a terminal on its host.")
|
||||
# return host_terminal
|
||||
|
||||
@property
|
||||
def _host_ransomware_script(self) -> RansomwareScript:
|
||||
"""Return the RansomwareScript that is installed on the same machine as the C2 Beacon."""
|
||||
ransomware_script: RansomwareScript = self.software_manager.software.get("RansomwareScript")
|
||||
if ransomware_script is None:
|
||||
self.sys_log.warning(f"{self.__class__.__name__} cannot find installed ransomware on its host.")
|
||||
return ransomware_script
|
||||
|
||||
def _init_request_manager(self) -> RequestManager:
|
||||
"""
|
||||
Initialise the request manager.
|
||||
@@ -87,6 +94,7 @@ class C2Beacon(AbstractC2, identifier="C2 Beacon"):
|
||||
)
|
||||
|
||||
c2_remote_ip = IPv4Address(c2_remote_ip)
|
||||
# TODO: validation.
|
||||
frequency = request[-1].get("keep_alive_frequency")
|
||||
protocol = request[-1].get("masquerade_protocol")
|
||||
port = request[-1].get("masquerade_port")
|
||||
@@ -127,7 +135,7 @@ class C2Beacon(AbstractC2, identifier="C2 Beacon"):
|
||||
:param masquerade_port: The Port that the C2 Traffic will masquerade as. Defaults to FTP.
|
||||
:type masquerade_port: Enum (Port)
|
||||
"""
|
||||
self.c2_remote_connection = c2_server_ip_address
|
||||
self.c2_remote_connection = IPv4Address(c2_server_ip_address)
|
||||
self.keep_alive_frequency = keep_alive_frequency
|
||||
self.current_masquerade_port = masquerade_port
|
||||
self.current_masquerade_protocol = masquerade_protocol
|
||||
@@ -252,7 +260,10 @@ class C2Beacon(AbstractC2, identifier="C2 Beacon"):
|
||||
:rtype: Request Response
|
||||
"""
|
||||
# TODO: replace and use terminal
|
||||
return RequestResponse(status="success", data={"Reason": "Placeholder."})
|
||||
# return RequestResponse(status="success", data={"Reason": "Placeholder."})
|
||||
given_config = payload.payload
|
||||
host_ransomware = self._host_ransomware_script
|
||||
return RequestResponse.from_bool(host_ransomware.configure(server_ip_address=given_config["server_ip_address"]))
|
||||
|
||||
def _command_ransomware_launch(self, payload: MasqueradePacket) -> RequestResponse:
|
||||
"""
|
||||
|
||||
@@ -48,8 +48,8 @@ class C2Server(AbstractC2, identifier="C2 Server"):
|
||||
:rtype: RequestResponse
|
||||
"""
|
||||
# TODO: Parse the parameters from the request to get the parameters
|
||||
placeholder: dict = {}
|
||||
return self._send_command(given_command=C2Command.RANSOMWARE_CONFIGURE, command_options=placeholder)
|
||||
ransomware_config = {"server_ip_address": request[-1].get("server_ip_address")}
|
||||
return self._send_command(given_command=C2Command.RANSOMWARE_CONFIGURE, command_options=ransomware_config)
|
||||
|
||||
def _launch_ransomware_action(request: RequestFormat, context: Dict) -> RequestResponse:
|
||||
"""Agent Action - Sends a RANSOMWARE_LAUNCH C2Command to the C2 Beacon with the given parameters.
|
||||
@@ -61,9 +61,7 @@ class C2Server(AbstractC2, identifier="C2 Server"):
|
||||
:return: RequestResponse object with a success code reflecting whether the ransomware was launched.
|
||||
:rtype: RequestResponse
|
||||
"""
|
||||
# TODO: Parse the parameters from the request to get the parameters
|
||||
placeholder: dict = {}
|
||||
return self._send_command(given_command=C2Command.RANSOMWARE_LAUNCH, command_options=placeholder)
|
||||
return self._send_command(given_command=C2Command.RANSOMWARE_LAUNCH, command_options={})
|
||||
|
||||
def _remote_terminal_action(request: RequestFormat, context: Dict) -> RequestResponse:
|
||||
"""Agent Action - Sends a TERMINAL C2Command to the C2 Beacon with the given parameters.
|
||||
@@ -77,18 +75,18 @@ class C2Server(AbstractC2, identifier="C2 Server"):
|
||||
"""
|
||||
# TODO: Parse the parameters from the request to get the parameters
|
||||
placeholder: dict = {}
|
||||
return self._send_command(given_command=C2Command.RANSOMWARE_LAUNCH, command_options=placeholder)
|
||||
return self._send_command(given_command=C2Command.TERMINAL, command_options=placeholder)
|
||||
|
||||
rm.add_request(
|
||||
name="c2_ransomware_configure",
|
||||
name="ransomware_configure",
|
||||
request_type=RequestType(func=_configure_ransomware_action),
|
||||
)
|
||||
rm.add_request(
|
||||
name="c2_ransomware_launch",
|
||||
name="ransomware_launch",
|
||||
request_type=RequestType(func=_launch_ransomware_action),
|
||||
)
|
||||
rm.add_request(
|
||||
name="c2_terminal_command",
|
||||
name="terminal_command",
|
||||
request_type=RequestType(func=_remote_terminal_action),
|
||||
)
|
||||
return rm
|
||||
@@ -203,7 +201,6 @@ class C2Server(AbstractC2, identifier="C2 Server"):
|
||||
self.sys_log.info(f"{self.name}: Attempting to send command {given_command}.")
|
||||
command_packet = self._craft_packet(given_command=given_command, command_options=command_options)
|
||||
|
||||
# Need to investigate if this is correct.
|
||||
if self.send(
|
||||
payload=command_packet,
|
||||
dest_ip_address=self.c2_remote_connection,
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
from ipaddress import IPv4Address
|
||||
from typing import Dict, Optional
|
||||
|
||||
from prettytable import MARKDOWN, PrettyTable
|
||||
|
||||
from primaite.interface.request import RequestFormat, RequestResponse
|
||||
from primaite.simulator.core import RequestManager, RequestType
|
||||
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
@@ -169,3 +171,25 @@ class RansomwareScript(Application, identifier="RansomwareScript"):
|
||||
else:
|
||||
self.sys_log.warning("Attack Attempted to launch too quickly")
|
||||
return False
|
||||
|
||||
def show(self, markdown: bool = False):
|
||||
"""
|
||||
Prints a table of the current status of the Ransomware Script.
|
||||
|
||||
Displays the current values of the following Ransomware Attributes:
|
||||
|
||||
``server_ip_address`:
|
||||
The IP of the target database.
|
||||
|
||||
``payload``:
|
||||
The payload (type of attack) to be sent to the database.
|
||||
|
||||
:param markdown: If True, outputs the table in markdown format. Default is False.
|
||||
"""
|
||||
table = PrettyTable(["Target Server IP Address", "Payload"])
|
||||
if markdown:
|
||||
table.set_style(MARKDOWN)
|
||||
table.align = "l"
|
||||
table.title = f"{self.name} Running Status"
|
||||
table.add_row([self.server_ip_address, self.payload])
|
||||
print(table)
|
||||
|
||||
Reference in New Issue
Block a user