forked from p15670423/monkey
Agent, UT: Implement VictimHostFactory
Implements and unit tests the VictimHostFactory. The factory allows creation of victims based on current network situation of the agent
This commit is contained in:
parent
ddd8a0e53a
commit
29d3cc2aaf
|
@ -89,7 +89,7 @@ class Propagator:
|
||||||
)
|
)
|
||||||
|
|
||||||
def _process_scan_results(self, address: NetworkAddress, scan_results: IPScanResults):
|
def _process_scan_results(self, address: NetworkAddress, scan_results: IPScanResults):
|
||||||
victim_host = self._victim_host_factory.build_victim_host(address.ip, address.domain)
|
victim_host = self._victim_host_factory.build_victim_host(address)
|
||||||
|
|
||||||
Propagator._process_ping_scan_results(victim_host, scan_results.ping_scan_data)
|
Propagator._process_ping_scan_results(victim_host, scan_results.ping_scan_data)
|
||||||
Propagator._process_tcp_scan_results(victim_host, scan_results.port_scan_data)
|
Propagator._process_tcp_scan_results(victim_host, scan_results.port_scan_data)
|
||||||
|
|
|
@ -1,28 +1,45 @@
|
||||||
|
import logging
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from infection_monkey.model import VictimHost
|
from infection_monkey.model import VictimHost
|
||||||
|
from infection_monkey.network import NetworkAddress
|
||||||
|
from infection_monkey.network.tools import get_interface_to_target
|
||||||
|
from infection_monkey.tunnel import MonkeyTunnel
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class VictimHostFactory:
|
class VictimHostFactory:
|
||||||
def __init__(self):
|
def __init__(
|
||||||
pass
|
self,
|
||||||
|
tunnel: Optional[MonkeyTunnel],
|
||||||
|
default_server: Optional[str],
|
||||||
|
default_port: Optional[str],
|
||||||
|
on_island: bool,
|
||||||
|
):
|
||||||
|
self.tunnel = tunnel
|
||||||
|
self.default_server = default_server
|
||||||
|
self.default_port = default_port
|
||||||
|
self.on_island = on_island
|
||||||
|
|
||||||
def build_victim_host(self, ip: str, domain: str):
|
def build_victim_host(self, network_address: NetworkAddress) -> VictimHost:
|
||||||
victim_host = VictimHost(ip, domain)
|
victim_host = VictimHost(network_address.ip, network_address.domain)
|
||||||
|
|
||||||
# TODO: Reimplement the below logic from the old monkey.py
|
if self.tunnel:
|
||||||
"""
|
victim_host.default_tunnel = self.tunnel.get_tunnel_for_ip(victim_host.ip_addr)
|
||||||
if self._monkey_tunnel:
|
if self.default_server:
|
||||||
self._monkey_tunnel.set_tunnel_for_host(machine)
|
if self.on_island:
|
||||||
if self._default_server:
|
victim_host.set_default_server(
|
||||||
if self._network.on_island(self._default_server):
|
get_interface_to_target(victim_host.ip_addr)
|
||||||
machine.set_default_server(
|
+ (":" + self.default_port if self.default_port else "")
|
||||||
get_interface_to_target(machine.ip_addr)
|
)
|
||||||
+ (":" + self._default_server_port if self._default_server_port else "")
|
else:
|
||||||
)
|
victim_host.set_default_server(self.default_server)
|
||||||
else:
|
logger.debug(
|
||||||
machine.set_default_server(self._default_server)
|
f"Default server for machine: {victim_host} set to {victim_host.default_server}"
|
||||||
logger.debug(
|
)
|
||||||
f"Default server for machine: {machine} set to {machine.default_server}"
|
logger.debug(
|
||||||
)
|
f"Default tunnel for machine: {victim_host} set to {victim_host.default_tunnel}"
|
||||||
"""
|
)
|
||||||
|
|
||||||
return victim_host
|
return victim_host
|
||||||
|
|
|
@ -4,7 +4,6 @@ import struct
|
||||||
import time
|
import time
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from infection_monkey.model import VictimHost
|
|
||||||
from infection_monkey.network.firewall import app as firewall
|
from infection_monkey.network.firewall import app as firewall
|
||||||
from infection_monkey.network.info import get_free_tcp_port, local_ips
|
from infection_monkey.network.info import get_free_tcp_port, local_ips
|
||||||
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
|
||||||
|
@ -188,14 +187,13 @@ class MonkeyTunnel(Thread):
|
||||||
proxy.stop()
|
proxy.stop()
|
||||||
proxy.join()
|
proxy.join()
|
||||||
|
|
||||||
def set_tunnel_for_host(self, host):
|
def get_tunnel_for_ip(self, ip: str):
|
||||||
assert isinstance(host, VictimHost)
|
|
||||||
|
|
||||||
if not self.local_port:
|
if not self.local_port:
|
||||||
return
|
return
|
||||||
|
|
||||||
ip_match = get_interface_to_target(host.ip_addr)
|
ip_match = get_interface_to_target(ip)
|
||||||
host.default_tunnel = "%s:%d" % (ip_match, self.local_port)
|
return "%s:%d" % (ip_match, self.local_port)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
|
|
|
@ -11,9 +11,26 @@ from infection_monkey.i_puppet import (
|
||||||
PortStatus,
|
PortStatus,
|
||||||
)
|
)
|
||||||
from infection_monkey.master import IPScanResults, Propagator
|
from infection_monkey.master import IPScanResults, Propagator
|
||||||
from infection_monkey.model import VictimHostFactory
|
|
||||||
from infection_monkey.network import NetworkInterface
|
from infection_monkey.network import NetworkInterface
|
||||||
from infection_monkey.telemetry.exploit_telem import ExploitTelem
|
from infection_monkey.telemetry.exploit_telem import ExploitTelem
|
||||||
|
from infection_monkey.model import VictimHost, VictimHostFactory
|
||||||
|
from infection_monkey.network import NetworkAddress
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_victim_host_factory():
|
||||||
|
class MockVictimHostFactory(VictimHostFactory):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_victim_host(self, network_address: NetworkAddress) -> VictimHost:
|
||||||
|
domain = network_address.domain or ""
|
||||||
|
return VictimHost(network_address.ip, domain)
|
||||||
|
|
||||||
|
return MockVictimHostFactory()
|
||||||
|
|
||||||
|
|
||||||
empty_fingerprint_data = FingerprintData(None, None, {})
|
empty_fingerprint_data = FingerprintData(None, None, {})
|
||||||
|
|
||||||
|
@ -111,9 +128,9 @@ class StubExploiter:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_scan_result_processing(telemetry_messenger_spy, mock_ip_scanner):
|
def test_scan_result_processing(telemetry_messenger_spy, mock_ip_scanner, mock_victim_host_factory):
|
||||||
p = Propagator(
|
p = Propagator(
|
||||||
telemetry_messenger_spy, mock_ip_scanner, StubExploiter(), VictimHostFactory(), []
|
telemetry_messenger_spy, mock_ip_scanner, StubExploiter(), mock_victim_host_factory, []
|
||||||
)
|
)
|
||||||
p.propagate(
|
p.propagate(
|
||||||
{
|
{
|
||||||
|
@ -201,9 +218,11 @@ class MockExploiter:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_exploiter_result_processing(telemetry_messenger_spy, mock_ip_scanner):
|
def test_exploiter_result_processing(
|
||||||
|
telemetry_messenger_spy, mock_ip_scanner, mock_victim_host_factory
|
||||||
|
):
|
||||||
p = Propagator(
|
p = Propagator(
|
||||||
telemetry_messenger_spy, mock_ip_scanner, MockExploiter(), VictimHostFactory(), []
|
telemetry_messenger_spy, mock_ip_scanner, MockExploiter(), mock_victim_host_factory, []
|
||||||
)
|
)
|
||||||
p.propagate(
|
p.propagate(
|
||||||
{
|
{
|
||||||
|
@ -240,13 +259,13 @@ def test_exploiter_result_processing(telemetry_messenger_spy, mock_ip_scanner):
|
||||||
assert data["result"]
|
assert data["result"]
|
||||||
|
|
||||||
|
|
||||||
def test_scan_target_generation(telemetry_messenger_spy, mock_ip_scanner):
|
def test_scan_target_generation(telemetry_messenger_spy, mock_ip_scanner, mock_victim_host_factory):
|
||||||
local_network_interfaces = [NetworkInterface("10.0.0.9", "/29")]
|
local_network_interfaces = [NetworkInterface("10.0.0.9", "/29")]
|
||||||
p = Propagator(
|
p = Propagator(
|
||||||
telemetry_messenger_spy,
|
telemetry_messenger_spy,
|
||||||
mock_ip_scanner,
|
mock_ip_scanner,
|
||||||
StubExploiter(),
|
StubExploiter(),
|
||||||
VictimHostFactory(),
|
mock_victim_host_factory,
|
||||||
local_network_interfaces,
|
local_network_interfaces,
|
||||||
)
|
)
|
||||||
p.propagate(
|
p.propagate(
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from infection_monkey.model import VictimHostFactory
|
||||||
|
from infection_monkey.network.scan_target_generator import NetworkAddress
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_tunnel():
|
||||||
|
tunnel = MagicMock()
|
||||||
|
tunnel.get_tunnel_for_ip = lambda _: "1.2.3.4:1234"
|
||||||
|
return tunnel
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def mock_get_interface_to_target(monkeypatch):
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"infection_monkey.model.victim_host_factory.get_interface_to_target", lambda _: "1.1.1.1"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_factory_no_tunnel():
|
||||||
|
factory = VictimHostFactory(
|
||||||
|
tunnel=None, default_server="192.168.56.1", default_port="5000", on_island=False
|
||||||
|
)
|
||||||
|
network_address = NetworkAddress("192.168.56.2", None)
|
||||||
|
|
||||||
|
victim = factory.build_victim_host(network_address)
|
||||||
|
|
||||||
|
assert victim.default_server == "192.168.56.1"
|
||||||
|
assert victim.ip_addr == "192.168.56.2"
|
||||||
|
assert victim.default_tunnel is None
|
||||||
|
assert victim.domain_name == ""
|
||||||
|
|
||||||
|
|
||||||
|
def test_factory_with_tunnel(mock_tunnel):
|
||||||
|
factory = VictimHostFactory(
|
||||||
|
tunnel=mock_tunnel, default_server="192.168.56.1", default_port="5000", on_island=False
|
||||||
|
)
|
||||||
|
network_address = NetworkAddress("192.168.56.2", None)
|
||||||
|
|
||||||
|
victim = factory.build_victim_host(network_address)
|
||||||
|
|
||||||
|
assert victim.default_server == "192.168.56.1"
|
||||||
|
assert victim.ip_addr == "192.168.56.2"
|
||||||
|
assert victim.default_tunnel == "1.2.3.4:1234"
|
||||||
|
assert victim.domain_name == ""
|
||||||
|
|
||||||
|
|
||||||
|
def test_factory_on_island(mock_tunnel):
|
||||||
|
factory = VictimHostFactory(
|
||||||
|
tunnel=mock_tunnel, default_server="192.168.56.1", default_port="99", on_island=True
|
||||||
|
)
|
||||||
|
network_address = NetworkAddress("192.168.56.2", "www.bogus.monkey")
|
||||||
|
|
||||||
|
victim = factory.build_victim_host(network_address)
|
||||||
|
|
||||||
|
assert victim.default_server == "1.1.1.1:99"
|
||||||
|
assert victim.domain_name == "www.bogus.monkey"
|
||||||
|
assert victim.ip_addr == "192.168.56.2"
|
||||||
|
assert victim.default_tunnel == "1.2.3.4:1234"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("default_port", ["", None])
|
||||||
|
def test_factory_no_port(mock_tunnel, default_port):
|
||||||
|
factory = VictimHostFactory(
|
||||||
|
tunnel=mock_tunnel, default_server="192.168.56.1", default_port=default_port, on_island=True
|
||||||
|
)
|
||||||
|
network_address = NetworkAddress("192.168.56.2", "www.bogus.monkey")
|
||||||
|
|
||||||
|
victim = factory.build_victim_host(network_address)
|
||||||
|
|
||||||
|
assert victim.default_server == "1.1.1.1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_factory_no_default_server(mock_tunnel):
|
||||||
|
factory = VictimHostFactory(
|
||||||
|
tunnel=mock_tunnel, default_server=None, default_port="", on_island=True
|
||||||
|
)
|
||||||
|
network_address = NetworkAddress("192.168.56.2", "www.bogus.monkey")
|
||||||
|
|
||||||
|
victim = factory.build_victim_host(network_address)
|
||||||
|
|
||||||
|
assert victim.default_server is None
|
Loading…
Reference in New Issue