-
Notifications
You must be signed in to change notification settings - Fork 792
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '3234-plugin' into develop
- Loading branch information
Showing
4 changed files
with
177 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import logging | ||
from functools import partial | ||
from pprint import pformat | ||
from typing import Any, Dict, Sequence | ||
|
||
# common imports | ||
from common.event_queue import IAgentEventPublisher | ||
from common.types import AgentID, Event | ||
from common.utils.code_utils import del_key | ||
|
||
# dependencies to get rid of or internalize | ||
from infection_monkey.exploit import IAgentBinaryRepository, IAgentOTPProvider | ||
from infection_monkey.exploit.tools import all_udp_ports_are_closed | ||
from infection_monkey.exploit.tools.http_agent_binary_server import start_agent_binary_server | ||
from infection_monkey.i_puppet import ExploiterResultData, TargetHost | ||
from infection_monkey.network import TCPPortSelector | ||
from infection_monkey.propagation_credentials_repository import IPropagationCredentialsRepository | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class StubSNMPOptions: | ||
def __init__(self, *args, **kwargs): | ||
pass | ||
|
||
|
||
class StubSNMPExploiter: | ||
def __init__(self, *args, **kwargs): | ||
pass | ||
|
||
def exploit_host(self, *args, **kwargs): | ||
pass | ||
|
||
|
||
class StubSNMPExploitClient: | ||
def __init__(self, *args, **kwargs): | ||
pass | ||
|
||
|
||
SNMP_PORTS = [161] | ||
|
||
|
||
def should_attempt_exploit(host: TargetHost) -> bool: | ||
return not all_udp_ports_are_closed(host, SNMP_PORTS) | ||
|
||
|
||
class Plugin: | ||
def __init__( | ||
self, | ||
*, | ||
plugin_name: str, | ||
agent_id: AgentID, | ||
agent_event_publisher: IAgentEventPublisher, | ||
agent_binary_repository: IAgentBinaryRepository, | ||
propagation_credentials_repository: IPropagationCredentialsRepository, | ||
tcp_port_selector: TCPPortSelector, | ||
otp_provider: IAgentOTPProvider, | ||
**kwargs, | ||
): | ||
exploit_client = StubSNMPExploitClient(agent_id, agent_event_publisher) | ||
agent_binary_server_factory = partial( | ||
start_agent_binary_server, | ||
agent_binary_repository=agent_binary_repository, | ||
tcp_port_selector=tcp_port_selector, | ||
) | ||
|
||
self._snmp_exploiter = StubSNMPExploiter( | ||
agent_id, | ||
exploit_client, | ||
agent_binary_server_factory, | ||
propagation_credentials_repository, | ||
otp_provider, | ||
) | ||
|
||
def run( | ||
self, | ||
*, | ||
host: TargetHost, | ||
servers: Sequence[str], | ||
current_depth: int, | ||
options: Dict[str, Any], | ||
interrupt: Event, | ||
**kwargs, | ||
) -> ExploiterResultData: | ||
# HTTP ports options are hack because they are needed in fingerprinters | ||
del_key(options, "http_ports") | ||
|
||
try: | ||
logger.debug(f"Parsing options: {pformat(options)}") | ||
snmp_options = StubSNMPOptions(**options) | ||
except Exception as err: | ||
msg = f"Failed to parse SNMP options: {err}" | ||
logger.exception(msg) | ||
return ExploiterResultData(error_message=msg) | ||
|
||
if not should_attempt_exploit(host): | ||
msg = f"Host {host.ip} has no open SNMP ports" | ||
logger.debug(msg) | ||
return ExploiterResultData( | ||
exploitation_success=False, propagation_success=False, error_message=msg | ||
) | ||
|
||
try: | ||
logger.debug(f"Running SNMP exploiter on host {host.ip}") | ||
return self._snmp_exploiter.exploit_host( | ||
host, servers, current_depth, snmp_options, interrupt | ||
) | ||
except Exception as err: | ||
msg = f"An unexpected exception occurred while attempting to exploit host: {err}" | ||
logger.exception(msg) | ||
return ExploiterResultData(error_message=msg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,21 @@ | ||
from typing import Sequence | ||
|
||
from common.types import NetworkPort | ||
from infection_monkey.i_puppet import TargetHost | ||
|
||
|
||
def all_exploitation_ports_are_closed(host: TargetHost, exploitation_ports: Sequence[int]) -> bool: | ||
closed_tcp_ports = host.ports_status.tcp_ports.closed | ||
return all([p in closed_tcp_ports for p in exploitation_ports]) | ||
|
||
|
||
def all_udp_ports_are_closed(host: TargetHost, udp_ports: Sequence[NetworkPort]) -> bool: | ||
""" | ||
Check if all UDP ports in a given sequence are closed on the host | ||
:param host: The host to check | ||
:param udp_ports: The sequence of UDP ports to check | ||
:return: True if all ports are closed, False otherwise | ||
""" | ||
closed_udp_ports = host.ports_status.udp_ports.closed | ||
return all([p in closed_udp_ports for p in udp_ports]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters