forked from p34709852/monkey
Agent: Process fingerprinter results in Propagator
This commit is contained in:
parent
438563af9c
commit
8067dc9ff8
|
@ -3,7 +3,7 @@ from queue import Queue
|
||||||
from threading import Event, Thread
|
from threading import Event, Thread
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from infection_monkey.i_puppet import PingScanData, PortScanData, PortStatus
|
from infection_monkey.i_puppet import FingerprintData, PingScanData, PortScanData, PortStatus
|
||||||
from infection_monkey.model.host import VictimHost
|
from infection_monkey.model.host import VictimHost
|
||||||
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger
|
||||||
from infection_monkey.telemetry.scan_telem import ScanTelem
|
from infection_monkey.telemetry.scan_telem import ScanTelem
|
||||||
|
@ -52,15 +52,33 @@ class Propagator:
|
||||||
logger.info("Finished network scan")
|
logger.info("Finished network scan")
|
||||||
|
|
||||||
def _process_scan_results(
|
def _process_scan_results(
|
||||||
self, ip: str, ping_scan_data: PingScanData, port_scan_data: Dict[int, PortScanData]
|
self,
|
||||||
|
ip: str,
|
||||||
|
ping_scan_data: PingScanData,
|
||||||
|
port_scan_data: Dict[int, PortScanData],
|
||||||
|
fingerprint_data: Dict[str, FingerprintData],
|
||||||
):
|
):
|
||||||
victim_host = VictimHost(ip)
|
victim_host = VictimHost(ip)
|
||||||
has_open_port = False
|
|
||||||
|
|
||||||
|
Propagator._process_ping_scan_results(victim_host, ping_scan_data)
|
||||||
|
has_open_port = Propagator._process_tcp_scan_results(victim_host, port_scan_data)
|
||||||
|
Propagator._process_fingerprinter_results(victim_host, fingerprint_data)
|
||||||
|
|
||||||
|
if has_open_port:
|
||||||
|
self._hosts_to_exploit.put(victim_host)
|
||||||
|
|
||||||
|
self._telemetry_messenger.send_telemetry(ScanTelem(victim_host))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _process_ping_scan_results(victim_host: VictimHost, ping_scan_data: PingScanData):
|
||||||
victim_host.icmp = ping_scan_data.response_received
|
victim_host.icmp = ping_scan_data.response_received
|
||||||
if ping_scan_data.os is not None:
|
if ping_scan_data.os is not None:
|
||||||
victim_host.os["type"] = ping_scan_data.os
|
victim_host.os["type"] = ping_scan_data.os
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _process_tcp_scan_results(victim_host: VictimHost, port_scan_data: PortScanData) -> bool:
|
||||||
|
has_open_port = False
|
||||||
|
|
||||||
for psd in port_scan_data.values():
|
for psd in port_scan_data.values():
|
||||||
if psd.status == PortStatus.OPEN:
|
if psd.status == PortStatus.OPEN:
|
||||||
has_open_port = True
|
has_open_port = True
|
||||||
|
@ -71,10 +89,19 @@ class Propagator:
|
||||||
if psd.banner is not None:
|
if psd.banner is not None:
|
||||||
victim_host.services[psd.service]["banner"] = psd.banner
|
victim_host.services[psd.service]["banner"] = psd.banner
|
||||||
|
|
||||||
if has_open_port:
|
return has_open_port
|
||||||
self._hosts_to_exploit.put(victim_host)
|
|
||||||
|
|
||||||
self._telemetry_messenger.send_telemetry(ScanTelem(victim_host))
|
@staticmethod
|
||||||
|
def _process_fingerprinter_results(victim_host: VictimHost, fingerprint_data: FingerprintData):
|
||||||
|
for fd in fingerprint_data.values():
|
||||||
|
if fd.os_type is not None:
|
||||||
|
victim_host.os["type"] = fd.os_type
|
||||||
|
|
||||||
|
if ("version" not in victim_host.os) and (fd.os_version is not None):
|
||||||
|
victim_host.os["version"] = fd.os_version
|
||||||
|
|
||||||
|
for service, details in fd.services.items():
|
||||||
|
victim_host.services.setdefault(service, {}).update(details)
|
||||||
|
|
||||||
def _exploit_targets(self, scan_thread: Thread, stop: Event):
|
def _exploit_targets(self, scan_thread: Thread, stop: Event):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from threading import Event
|
from threading import Event
|
||||||
|
|
||||||
from infection_monkey.i_puppet import PingScanData, PortScanData, PortStatus
|
from infection_monkey.i_puppet import FingerprintData, PingScanData, PortScanData, PortStatus
|
||||||
from infection_monkey.master import Propagator
|
from infection_monkey.master import Propagator
|
||||||
|
|
||||||
|
empty_fingerprint_data = FingerprintData(None, None, {})
|
||||||
|
|
||||||
dot_1_results = (
|
dot_1_results = (
|
||||||
PingScanData(True, "windows"),
|
PingScanData(True, "windows"),
|
||||||
{
|
{
|
||||||
|
@ -10,6 +12,11 @@ dot_1_results = (
|
||||||
445: PortScanData(445, PortStatus.OPEN, "SMB BANNER", "tcp-445"),
|
445: PortScanData(445, PortStatus.OPEN, "SMB BANNER", "tcp-445"),
|
||||||
3389: PortScanData(3389, PortStatus.OPEN, "", "tcp-3389"),
|
3389: PortScanData(3389, PortStatus.OPEN, "", "tcp-3389"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"SMBFinger": FingerprintData("windows", "vista", {"tcp-445": {"name": "smb_service_name"}}),
|
||||||
|
"SSHFinger": empty_fingerprint_data,
|
||||||
|
"HTTPFinger": empty_fingerprint_data,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
dot_3_results = (
|
dot_3_results = (
|
||||||
|
@ -19,6 +26,20 @@ dot_3_results = (
|
||||||
443: PortScanData(443, PortStatus.OPEN, "HTTPS BANNER", "tcp-443"),
|
443: PortScanData(443, PortStatus.OPEN, "HTTPS BANNER", "tcp-443"),
|
||||||
3389: PortScanData(3389, PortStatus.CLOSED, "", None),
|
3389: PortScanData(3389, PortStatus.CLOSED, "", None),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"SSHFinger": FingerprintData(
|
||||||
|
"linux", "ubuntu", {"tcp-22": {"name": "SSH", "banner": "SSH BANNER"}}
|
||||||
|
),
|
||||||
|
"HTTPFinger": FingerprintData(
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
{
|
||||||
|
"tcp-80": {"name": "http", "data": ("SERVER_HEADERS", False)},
|
||||||
|
"tcp-443": {"name": "http", "data": ("SERVER_HEADERS_2", True)},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"SMBFinger": empty_fingerprint_data,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
dead_host_results = (
|
dead_host_results = (
|
||||||
|
@ -28,21 +49,34 @@ dead_host_results = (
|
||||||
443: PortScanData(443, PortStatus.CLOSED, None, None),
|
443: PortScanData(443, PortStatus.CLOSED, None, None),
|
||||||
3389: PortScanData(3389, PortStatus.CLOSED, "", None),
|
3389: PortScanData(3389, PortStatus.CLOSED, "", None),
|
||||||
},
|
},
|
||||||
|
{},
|
||||||
)
|
)
|
||||||
|
|
||||||
dot_1_services = {
|
dot_1_services = {
|
||||||
"tcp-445": {"display_name": "unknown(TCP)", "port": 445, "banner": "SMB BANNER"},
|
"tcp-445": {
|
||||||
|
"name": "smb_service_name",
|
||||||
|
"display_name": "unknown(TCP)",
|
||||||
|
"port": 445,
|
||||||
|
"banner": "SMB BANNER",
|
||||||
|
},
|
||||||
"tcp-3389": {"display_name": "unknown(TCP)", "port": 3389, "banner": ""},
|
"tcp-3389": {"display_name": "unknown(TCP)", "port": 3389, "banner": ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
dot_3_services = {
|
dot_3_services = {
|
||||||
"tcp-22": {"display_name": "unknown(TCP)", "port": 22, "banner": "SSH BANNER"},
|
"tcp-22": {"name": "SSH", "display_name": "unknown(TCP)", "port": 22, "banner": "SSH BANNER"},
|
||||||
"tcp-443": {"display_name": "unknown(TCP)", "port": 443, "banner": "HTTPS BANNER"},
|
"tcp-80": {"name": "http", "data": ("SERVER_HEADERS", False)},
|
||||||
|
"tcp-443": {
|
||||||
|
"name": "http",
|
||||||
|
"display_name": "unknown(TCP)",
|
||||||
|
"port": 443,
|
||||||
|
"banner": "HTTPS BANNER",
|
||||||
|
"data": ("SERVER_HEADERS_2", True),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class MockIPScanner:
|
class MockIPScanner:
|
||||||
def scan(self, ips_to_scan, options, results_callback, stop):
|
def scan(self, ips_to_scan, _, results_callback, stop):
|
||||||
for ip in ips_to_scan:
|
for ip in ips_to_scan:
|
||||||
if ip.endswith(".1"):
|
if ip.endswith(".1"):
|
||||||
results_callback(ip, *dot_1_results)
|
results_callback(ip, *dot_1_results)
|
||||||
|
@ -55,7 +89,10 @@ class MockIPScanner:
|
||||||
def test_scan_result_processing(telemetry_messenger_spy):
|
def test_scan_result_processing(telemetry_messenger_spy):
|
||||||
p = Propagator(telemetry_messenger_spy, MockIPScanner())
|
p = Propagator(telemetry_messenger_spy, MockIPScanner())
|
||||||
p.propagate(
|
p.propagate(
|
||||||
{"targets": {"subnet_scan_list": ["10.0.0.1", "10.0.0.2", "10.0.0.3"]}, "network_scan": {}},
|
{
|
||||||
|
"targets": {"subnet_scan_list": ["10.0.0.1", "10.0.0.2", "10.0.0.3"]},
|
||||||
|
"network_scan": {},
|
||||||
|
},
|
||||||
Event(),
|
Event(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -68,11 +105,13 @@ def test_scan_result_processing(telemetry_messenger_spy):
|
||||||
if ip.endswith(".1"):
|
if ip.endswith(".1"):
|
||||||
assert data["service_count"] == 2
|
assert data["service_count"] == 2
|
||||||
assert data["machine"]["os"]["type"] == "windows"
|
assert data["machine"]["os"]["type"] == "windows"
|
||||||
|
assert data["machine"]["os"]["version"] == "vista"
|
||||||
assert data["machine"]["services"] == dot_1_services
|
assert data["machine"]["services"] == dot_1_services
|
||||||
assert data["machine"]["icmp"] is True
|
assert data["machine"]["icmp"] is True
|
||||||
elif ip.endswith(".3"):
|
elif ip.endswith(".3"):
|
||||||
assert data["service_count"] == 2
|
assert data["service_count"] == 3
|
||||||
assert data["machine"]["os"]["type"] == "linux"
|
assert data["machine"]["os"]["type"] == "linux"
|
||||||
|
assert data["machine"]["os"]["version"] == "ubuntu"
|
||||||
assert data["machine"]["services"] == dot_3_services
|
assert data["machine"]["services"] == dot_3_services
|
||||||
assert data["machine"]["icmp"] is True
|
assert data["machine"]["icmp"] is True
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue