Merge pull request #2348 from guardicore/2299-rename-local-network-scan

Island: Rename local_network_scan
This commit is contained in:
VakarisZ 2022-09-27 16:00:36 +03:00 committed by GitHub
commit 9823301c3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 100 additions and 97 deletions

View File

@ -22,7 +22,7 @@ _custom_pba_configuration = CustomPBAConfiguration(
_tcp_scan_configuration = TCPScanConfiguration(timeout=3.0, ports=[])
_icmp_scan_configuration = ICMPScanConfiguration(timeout=1.0)
_scan_target_configuration = ScanTargetConfiguration(
blocked_ips=[], inaccessible_subnets=[], local_network_scan=False, subnets=[]
blocked_ips=[], inaccessible_subnets=[], scan_my_networks=False, subnets=[]
)
_network_scan_configuration = NetworkScanConfiguration(
tcp=_tcp_scan_configuration,

View File

@ -79,7 +79,8 @@ class ScanTargetConfiguration(MutableInfectionMonkeyBaseModel):
Example: ("1.1.1.1", "2.2.2.2")
:param inaccessible_subnets: Subnet ranges that shouldn't be accessible for the agent
Example: ("1.1.1.1", "2.2.2.2/24", "myserver")
:param local_network_scan: Whether or not the agent should scan the local network
:param scan_my_networks: If true the Agent will scan networks it belongs to
in addition to the provided subnet ranges
:param subnets: Subnet ranges to scan
Example: ("192.168.1.1-192.168.2.255", "3.3.3.3", "2.2.2.2/24",
"myHostname")
@ -87,7 +88,7 @@ class ScanTargetConfiguration(MutableInfectionMonkeyBaseModel):
blocked_ips: Tuple[str, ...]
inaccessible_subnets: Tuple[str, ...]
local_network_scan: bool
scan_my_networks: bool
subnets: Tuple[str, ...]
@validator("blocked_ips", each_item=True)

View File

@ -78,7 +78,7 @@ FINGERPRINTERS = (
)
SCAN_TARGET_CONFIGURATION = ScanTargetConfiguration(
blocked_ips=tuple(), inaccessible_subnets=tuple(), local_network_scan=True, subnets=tuple()
blocked_ips=tuple(), inaccessible_subnets=tuple(), scan_my_networks=True, subnets=tuple()
)
NETWORK_SCAN_CONFIGURATION = NetworkScanConfiguration(
tcp=TCP_SCAN_CONFIGURATION,

View File

@ -4,7 +4,7 @@ import random
import socket
import struct
from abc import ABCMeta, abstractmethod
from typing import List, Tuple
from typing import Iterable, List, Tuple
logger = logging.getLogger(__name__)
@ -58,7 +58,7 @@ class NetworkRange(object, metaclass=ABCMeta):
return SingleIpRange(ip_address=address_str)
@staticmethod
def filter_invalid_ranges(ranges: List[str], error_msg: str) -> List[str]:
def filter_invalid_ranges(ranges: Iterable[str], error_msg: str) -> List[str]:
valid_ranges = []
for target_range in ranges:
try:

View File

@ -116,14 +116,14 @@ class Propagator:
ranges_to_scan = target_config.subnets
inaccessible_subnets = target_config.inaccessible_subnets
blocklisted_ips = target_config.blocked_ips
enable_local_network_scan = target_config.local_network_scan
scan_my_networks = target_config.scan_my_networks
return compile_scan_target_list(
self._local_network_interfaces,
ranges_to_scan,
inaccessible_subnets,
blocklisted_ips,
enable_local_network_scan,
scan_my_networks,
)
def _process_scan_results(self, address: NetworkAddress, scan_results: IPScanResults):

View File

@ -4,7 +4,7 @@ import struct
from dataclasses import dataclass
from random import shuffle # noqa: DUO102
from threading import Lock
from typing import Dict, Set
from typing import Dict, Optional, Set
import netifaces
import psutil
@ -25,7 +25,7 @@ RTF_REJECT = 0x0200
@dataclass
class NetworkAddress:
ip: str
domain: str
domain: Optional[str]
def get_host_subnets():

View File

@ -2,34 +2,31 @@ import itertools
import logging
import socket
from ipaddress import IPv4Interface
from typing import Dict, List, Sequence
from typing import Dict, Iterable, List, Optional, Sequence
from common.network.network_range import InvalidNetworkRangeError, NetworkRange
from infection_monkey.network import NetworkAddress
logger = logging.getLogger(__name__)
# TODO: We can probably reduce code and save ourselves some trouble if we use IPv4Address and
# IPv4Network. See https://docs.python.org/3/library/ipaddress.html
def compile_scan_target_list(
local_network_interfaces: Sequence[IPv4Interface],
ranges_to_scan: Sequence[str],
inaccessible_subnets: Sequence[str],
blocklisted_ips: Sequence[str],
enable_local_network_scan: bool,
scan_my_networks: bool,
) -> List[NetworkAddress]:
scan_targets = _get_ips_from_subnets_to_scan(ranges_to_scan)
if enable_local_network_scan:
scan_targets.extend(_get_ips_to_scan_from_local_interface(local_network_interfaces))
if scan_my_networks:
scan_targets.extend(_get_ips_to_scan_from_interface(local_network_interfaces))
if inaccessible_subnets:
inaccessible_subnets = _get_segmentation_check_targets(
other_targets = _get_segmentation_check_targets(
inaccessible_subnets, local_network_interfaces
)
scan_targets.extend(inaccessible_subnets)
scan_targets.extend(other_targets)
scan_targets = _remove_interface_ips(scan_targets, local_network_interfaces)
scan_targets = _remove_blocklisted_ips(scan_targets, blocklisted_ips)
@ -39,8 +36,8 @@ def compile_scan_target_list(
return scan_targets
def _remove_redundant_targets(targets: List[NetworkAddress]) -> List[NetworkAddress]:
reverse_dns: Dict[str, str] = {}
def _remove_redundant_targets(targets: Sequence[NetworkAddress]) -> List[NetworkAddress]:
reverse_dns: Dict[str, Optional[str]] = {}
for target in targets:
domain_name = target.domain
ip = target.ip
@ -52,14 +49,15 @@ def _remove_redundant_targets(targets: List[NetworkAddress]) -> List[NetworkAddr
def _range_to_addresses(range_obj: NetworkRange) -> List[NetworkAddress]:
addresses = []
for address in range_obj:
if hasattr(range_obj, "domain_name"):
addresses.append(NetworkAddress(address, range_obj.domain_name))
else:
addresses.append(NetworkAddress(address, None))
try:
domain = range_obj.domain_name # type: ignore
except AttributeError:
domain = None
addresses.append(NetworkAddress(address, domain))
return addresses
def _get_ips_from_subnets_to_scan(subnets_to_scan: List[str]) -> List[NetworkAddress]:
def _get_ips_from_subnets_to_scan(subnets_to_scan: Iterable[str]) -> List[NetworkAddress]:
ranges_to_scan = NetworkRange.filter_invalid_ranges(
subnets_to_scan, "Bad network range input for targets to scan:"
)
@ -68,7 +66,7 @@ def _get_ips_from_subnets_to_scan(subnets_to_scan: List[str]) -> List[NetworkAdd
return _get_ips_from_ranges_to_scan(network_ranges)
def _get_ips_from_ranges_to_scan(network_ranges: List[NetworkRange]) -> List[NetworkAddress]:
def _get_ips_from_ranges_to_scan(network_ranges: Iterable[NetworkRange]) -> List[NetworkAddress]:
scan_targets = []
for _range in network_ranges:
@ -76,8 +74,8 @@ def _get_ips_from_ranges_to_scan(network_ranges: List[NetworkRange]) -> List[Net
return scan_targets
def _get_ips_to_scan_from_local_interface(
interfaces: List[IPv4Interface],
def _get_ips_to_scan_from_interface(
interfaces: Sequence[IPv4Interface],
) -> List[NetworkAddress]:
ranges = [str(interface) for interface in interfaces]
@ -88,14 +86,14 @@ def _get_ips_to_scan_from_local_interface(
def _remove_interface_ips(
scan_targets: List[NetworkAddress], interfaces: List[IPv4Interface]
scan_targets: Sequence[NetworkAddress], interfaces: Iterable[IPv4Interface]
) -> List[NetworkAddress]:
interface_ips = [str(interface.ip) for interface in interfaces]
return _remove_ips_from_scan_targets(scan_targets, interface_ips)
def _remove_blocklisted_ips(
scan_targets: List[NetworkAddress], blocked_ips: List[str]
scan_targets: Sequence[NetworkAddress], blocked_ips: Sequence[str]
) -> List[NetworkAddress]:
filtered_blocked_ips = NetworkRange.filter_invalid_ranges(
blocked_ips, "Invalid blocked IP provided:"
@ -106,14 +104,14 @@ def _remove_blocklisted_ips(
def _remove_ips_from_scan_targets(
scan_targets: List[NetworkAddress], ips_to_remove: List[str]
scan_targets: Sequence[NetworkAddress], ips_to_remove: Iterable[str]
) -> List[NetworkAddress]:
ips_to_remove_set = set(ips_to_remove)
return [address for address in scan_targets if address.ip not in ips_to_remove_set]
def _get_segmentation_check_targets(
inaccessible_subnets: List[str], local_interfaces: List[IPv4Interface]
inaccessible_subnets: Iterable[str], local_interfaces: Iterable[IPv4Interface]
) -> List[NetworkAddress]:
ips_to_scan = []
local_ips = [str(interface.ip) for interface in local_interfaces]
@ -134,17 +132,17 @@ def _get_segmentation_check_targets(
return ips_to_scan
def _convert_to_range_object(subnets: List[str]) -> List[NetworkRange]:
def _convert_to_range_object(subnets: Iterable[str]) -> List[NetworkRange]:
return [NetworkRange.get_range_obj(subnet) for subnet in subnets]
def _is_segmentation_check_required(
local_ips: List[str], subnet1: NetworkRange, subnet2: NetworkRange
local_ips: Sequence[str], subnet1: NetworkRange, subnet2: NetworkRange
):
return _is_any_ip_in_subnet(local_ips, subnet1) and not _is_any_ip_in_subnet(local_ips, subnet2)
def _is_any_ip_in_subnet(ip_addresses: List[str], subnet: NetworkRange):
def _is_any_ip_in_subnet(ip_addresses: Iterable[str], subnet: NetworkRange):
for ip_address in ip_addresses:
if subnet.is_in_range(ip_address):
return True

View File

@ -398,7 +398,7 @@ class ReportService:
@classmethod
def get_config_scan(cls):
agent_configuration = cls._agent_configuration_repository.get_configuration()
return agent_configuration.propagation.network_scan.targets.local_network_scan
return agent_configuration.propagation.network_scan.targets.scan_my_networks
@staticmethod
def get_issue_set(issues):

View File

@ -14,12 +14,12 @@ const PROPAGATION_CONFIGURATION_SCHEMA = {
'minimum': 0,
'default': 2,
'description': 'Amount of hops allowed for the monkey to spread from the ' +
'Island server. \n' +
' \u26A0' +
' Note that setting this value too high may result in the ' +
'Monkey propagating too far, '+
'if "Local network scan" is enabled.\n' +
'Setting this to 0 will disable all scanning and exploitation.'
'Island server. \n' +
' \u26A0' +
' Note that setting this value too high may result in the ' +
'Monkey propagating too far, ' +
'if "Scan Agent\'s networks" is enabled.\n' +
'Setting this to 0 will disable all scanning and exploitation.'
},
'network_scan': NETWORK_SCAN_CONFIGURATION_SCHEMA
}

View File

@ -3,8 +3,9 @@ const SCAN_TARGET_CONFIGURATION_SCHEMA = {
'type': 'object',
'properties': {
'info_box': {
'info': 'The Monkey scans its subnet if "Local network scan" is checked. '+
'Additionally, the Monkey scans machines according to "Scan target list". '
'info': 'The Monkey scans for machines on each of the network interfaces of the ' +
'machine it is running on if "Scan Agent\'s networks" is checked. ' +
'Additionally, the Monkey scans machines according to "Scan target list". '
},
'blocked_ips': {
'title': 'Blocked IPs',
@ -27,25 +28,28 @@ const SCAN_TARGET_CONFIGURATION_SCHEMA = {
},
'default': [],
'description': 'Test for network segmentation by providing a list of network segments that should NOT be accessible to each other.\n\n ' +
'For example, if you configured the following three segments: ' +
'"10.0.0.0/24", "11.0.0.2/32" and "12.2.3.0/24",' +
'a Monkey running on 10.0.0.5 will try to access machines in ' +
'the following subnets: ' +
'11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment connections ' +
'will be shown in the reports. \n\n' +
'Network segments can be IPs, subnets or hosts. Examples:\n' +
'\tDefine a single-IP segment: "192.168.0.1"\n' +
'\tDefine a segment using a network range: ' +
'"192.168.0.5-192.168.0.20"\n' +
'\tDefine a segment using an subnet IP mask: "192.168.0.5/24"\n' +
'\tDefine a single-host segment: "printer.example"'
'For example, if you configured the following three segments: ' +
'"10.0.0.0/24", "11.0.0.2/32" and "12.2.3.0/24",' +
'a Monkey running on 10.0.0.5 will try to access machines in ' +
'the following subnets: ' +
'11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment connections ' +
'will be shown in the reports. \n\n' +
'Network segments can be IPs, subnets or hosts. Examples:\n' +
'\tDefine a single-IP segment: "192.168.0.1"\n' +
'\tDefine a segment using a network range: ' +
'"192.168.0.5-192.168.0.20"\n' +
'\tDefine a segment using an subnet IP mask: "192.168.0.5/24"\n' +
'\tDefine a single-host segment: "printer.example"'
},
'local_network_scan': {
'title': 'Local network scan',
'scan_my_networks': {
'title': 'Scan Agent\'s networks',
'type': 'boolean',
'default': true,
'description': 'Determines whether the Monkey will scan the local subnets of machines it runs on, ' +
'in addition to the IPs that are configured manually in the "Scan target list"'
'default': false,
'description': 'If enabled, the Agent will go over all network interfaces and ' +
'will scan their networks,' +
' in addition to the IPs that are configured manually in the "Scan target list". ' +
'Note: If the Agent runs on a machine within a public network,' +
' this setting will cause scanning and exploitation attempts on that network.'
},
'subnets': {
'title': 'Scan target list',
@ -57,13 +61,13 @@ const SCAN_TARGET_CONFIGURATION_SCHEMA = {
},
'default': [],
'description': 'List of targets the Monkey will try to scan. Targets can be ' +
'IPs, subnets or hosts. ' +
'Examples:\n' +
'\tTarget a specific IP: "192.168.0.1"\n' +
'\tTarget a subnet using a network range: ' +
'"192.168.0.5-192.168.0.20"\n'+
'\tTarget a subnet using an IP mask: "192.168.0.5/24"\n' +
'\tTarget a specific host: "printer.example"'
'IPs, subnets or hosts. ' +
'Examples:\n' +
'\tTarget a specific IP: "192.168.0.1"\n' +
'\tTarget a subnet using a network range: ' +
'"192.168.0.5-192.168.0.20"\n' +
'\tTarget a subnet using an IP mask: "192.168.0.5/24"\n' +
'\tTarget a specific host: "printer.example"'
}
}

View File

@ -15,12 +15,12 @@ CUSTOM_PBA_CONFIGURATION = {
BLOCKED_IPS = ["10.0.0.1", "192.168.1.1"]
INACCESSIBLE_SUBNETS = ["172.0.0.0/24", "172.2.2.0/24", "192.168.56.0/24"]
LOCAL_NETWORK_SCAN = True
SCAN_MY_NETWORKS = True
SUBNETS = ["10.0.0.2", "10.0.0.2/16"]
SCAN_TARGET_CONFIGURATION = {
"blocked_ips": BLOCKED_IPS,
"inaccessible_subnets": INACCESSIBLE_SUBNETS,
"local_network_scan": LOCAL_NETWORK_SCAN,
"scan_my_networks": SCAN_MY_NETWORKS,
"subnets": SUBNETS,
}

View File

@ -9,13 +9,13 @@ from tests.common.example_agent_configuration import (
INACCESSIBLE_SUBNETS,
LINUX_COMMAND,
LINUX_FILENAME,
LOCAL_NETWORK_SCAN,
NETWORK_SCAN_CONFIGURATION,
PLUGIN_CONFIGURATION,
PLUGIN_NAME,
PLUGIN_OPTIONS,
PORTS,
PROPAGATION_CONFIGURATION,
SCAN_MY_NETWORKS,
SCAN_TARGET_CONFIGURATION,
SUBNETS,
TCP_SCAN_CONFIGURATION,
@ -93,7 +93,7 @@ def test_scan_target_configuration():
assert config.blocked_ips == tuple(BLOCKED_IPS)
assert config.inaccessible_subnets == tuple(INACCESSIBLE_SUBNETS)
assert config.local_network_scan == LOCAL_NETWORK_SCAN
assert config.scan_my_networks == SCAN_MY_NETWORKS
assert config.subnets == tuple(SUBNETS)
@ -174,7 +174,7 @@ def test_network_scan_configuration():
assert config.fingerprinters[0].options == FINGERPRINTERS[0]["options"]
assert config.targets.blocked_ips == tuple(BLOCKED_IPS)
assert config.targets.inaccessible_subnets == tuple(INACCESSIBLE_SUBNETS)
assert config.targets.local_network_scan == LOCAL_NETWORK_SCAN
assert config.targets.scan_my_networks == SCAN_MY_NETWORKS
assert config.targets.subnets == tuple(SUBNETS)

View File

@ -166,7 +166,7 @@ def test_scan_result_processing(
targets = ScanTargetConfiguration(
blocked_ips=[],
inaccessible_subnets=[],
local_network_scan=False,
scan_my_networks=False,
subnets=["10.0.0.1", "10.0.0.2", "10.0.0.3"],
)
propagation_config = get_propagation_config(default_agent_configuration, targets)
@ -265,7 +265,7 @@ def test_exploiter_result_processing(
targets = ScanTargetConfiguration(
blocked_ips=[],
inaccessible_subnets=[],
local_network_scan=False,
scan_my_networks=False,
subnets=["10.0.0.1", "10.0.0.2", "10.0.0.3"],
)
propagation_config = get_propagation_config(default_agent_configuration, targets)
@ -306,7 +306,7 @@ def test_scan_target_generation(
targets = ScanTargetConfiguration(
blocked_ips=["10.0.0.3"],
inaccessible_subnets=["10.0.0.128/30", "10.0.0.8/29"],
local_network_scan=True,
scan_my_networks=True,
subnets=["10.0.0.0/29", "172.10.20.30"],
)
propagation_config = get_propagation_config(default_agent_configuration, targets)

View File

@ -14,7 +14,7 @@ def compile_ranges_only(ranges):
ranges_to_scan=ranges,
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
@ -88,7 +88,7 @@ def test_blocklisted_ips():
ranges_to_scan=["10.0.0.0/24"],
inaccessible_subnets=[],
blocklisted_ips=blocklisted_ips,
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 252
@ -105,7 +105,7 @@ def test_only_ip_blocklisted(ranges_to_scan):
ranges_to_scan=ranges_to_scan,
inaccessible_subnets=[],
blocklisted_ips=blocklisted_ips,
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 0
@ -124,7 +124,7 @@ def test_local_network_interface_ips_removed_from_targets():
ranges_to_scan=["10.0.0.0/24"],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 252
@ -142,7 +142,7 @@ def test_no_redundant_targets():
ranges_to_scan=["127.0.0.0", "127.0.0.1", "localhost"],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 2
@ -164,7 +164,7 @@ def test_only_scan_ip_is_local(ranges_to_scan):
ranges_to_scan=ranges_to_scan,
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 0
@ -184,7 +184,7 @@ def test_local_network_interface_ips_and_blocked_ips_removed_from_targets():
ranges_to_scan=["10.0.0.0/24", "192.168.1.0/24"],
inaccessible_subnets=[],
blocklisted_ips=blocked_ips,
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == (2 * (256 - 1)) - len(local_network_interfaces) - (
@ -206,7 +206,7 @@ def test_local_subnet_added():
ranges_to_scan=[],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=True,
scan_my_networks=True,
)
assert len(scan_targets) == 254
@ -226,7 +226,7 @@ def test_multiple_local_subnets_added():
ranges_to_scan=[],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=True,
scan_my_networks=True,
)
assert len(scan_targets) == 2 * (255 - 1)
@ -250,7 +250,7 @@ def test_blocklisted_ips_missing_from_local_subnets():
ranges_to_scan=[],
inaccessible_subnets=[],
blocklisted_ips=blocklisted_ips,
enable_local_network_scan=True,
scan_my_networks=True,
)
assert len(scan_targets) == 2 * (255 - 1) - len(blocklisted_ips)
@ -267,7 +267,7 @@ def test_local_subnets_and_ranges_added():
ranges_to_scan=["172.33.66.40/30"],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=True,
scan_my_networks=True,
)
assert len(scan_targets) == 254 + 3
@ -289,7 +289,7 @@ def test_local_network_interfaces_specified_but_disabled():
ranges_to_scan=["172.33.66.40/30"],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 3
@ -309,7 +309,7 @@ def test_local_network_interfaces_subnet_masks():
ranges_to_scan=[],
inaccessible_subnets=[],
blocklisted_ips=[],
enable_local_network_scan=True,
scan_my_networks=True,
)
assert len(scan_targets) == 4
@ -328,7 +328,7 @@ def test_segmentation_targets():
ranges_to_scan=[],
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 3
@ -351,7 +351,7 @@ def test_segmentation_clash_with_blocked():
ranges_to_scan=[],
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=blocked,
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 0
@ -371,7 +371,7 @@ def test_segmentation_clash_with_targets():
ranges_to_scan=targets,
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 3
@ -394,7 +394,7 @@ def test_segmentation_one_network():
ranges_to_scan=targets,
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 3
@ -413,7 +413,7 @@ def test_segmentation_inaccessible_networks():
ranges_to_scan=[],
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 0
@ -437,7 +437,7 @@ def test_invalid_inputs():
ranges_to_scan=targets,
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=[],
enable_local_network_scan=False,
scan_my_networks=False,
)
assert len(scan_targets) == 3
@ -461,7 +461,7 @@ def test_invalid_blocklisted_ip():
ranges_to_scan=targets,
inaccessible_subnets=inaccessible_subnets,
blocklisted_ips=blocklisted,
enable_local_network_scan=False,
scan_my_networks=False,
)