Iterate over ranges as chunks rather than discrete addresses

This commit is contained in:
Daniel Goldberg 2019-09-09 10:21:02 +03:00
parent 17dc764f37
commit 7357c8c168
1 changed files with 45 additions and 27 deletions

View File

@ -1,3 +1,4 @@
import itertools
import time import time
from common.network.network_range import * from common.network.network_range import *
@ -11,6 +12,22 @@ __author__ = 'itamar'
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
SCAN_DELAY = 0 SCAN_DELAY = 0
ITERATION_BLOCK_SIZE = 5
def _grouper(iterables, chunk_size):
"""
Goes over an iterable using chunks
:param iterables: a sequence of iterable objects
:param chunk_size: Chunk size, last chunk may be smaller
:return:
"""
iterable = itertools.chain(*iterables)
while True:
group = tuple(itertools.islice(iterable, chunk_size))
if not group:
break
yield group
class NetworkScanner(object): class NetworkScanner(object):
@ -69,35 +86,37 @@ class NetworkScanner(object):
:return: yields a sequence of VictimHost instances :return: yields a sequence of VictimHost instances
""" """
TCPscan = TcpScanner() tcp_scan = TcpScanner()
Pinger = PingScanner() ping_scan = PingScanner()
victims_count = 0 victims_count = 0
for network_chunk in _grouper(self._ranges, ITERATION_BLOCK_SIZE):
LOG.debug("Scanning for potential victims in chunk %r", network_chunk)
victim_chunk = []
for address in network_chunk:
#if hasattr(net_range, 'domain_name'):
# victim = VictimHost(address, net_range.domain_name)
#else:
victim = VictimHost(address)
for net_range in self._ranges: victim_chunk.append(victim)
LOG.debug("Scanning for potential victims in the network %r", net_range) # skip self IP addresses
for ip_addr in net_range: victim_chunk = [x for x in victim_chunk if x.ip_addr not in self._ip_addresses]
if hasattr(net_range, 'domain_name'): # skip IPs marked as blocked
victim = VictimHost(ip_addr, net_range.domain_name)
else:
victim = VictimHost(ip_addr)
if stop_callback and stop_callback():
LOG.debug("Got stop signal")
break
# skip self IP address bad_victims = [x for x in victim_chunk if x.ip_addr in WormConfiguration.blocked_ips]
if victim.ip_addr in self._ip_addresses: for victim in bad_victims:
continue LOG.info("Skipping %s due to blacklist" % victim)
victim_chunk = [x for x in victim_chunk if x.ip_addr not in WormConfiguration.blocked_ips]
# skip IPs marked as blocked # check before running scans
if victim.ip_addr in WormConfiguration.blocked_ips: if stop_callback and stop_callback():
LOG.info("Skipping %s due to blacklist" % victim) LOG.debug("Got stop signal")
continue break
for victim in victim_chunk:
LOG.debug("Scanning %r...", victim) LOG.debug("Scanning %r...", victim)
pingAlive = Pinger.is_host_alive(victim) pingAlive = ping_scan.is_host_alive(victim)
tcpAlive = TCPscan.is_host_alive(victim) tcpAlive = tcp_scan.is_host_alive(victim)
# if scanner detect machine is up, add it to victims list
if pingAlive or tcpAlive: if pingAlive or tcpAlive:
LOG.debug("Found potential victim: %r", victim) LOG.debug("Found potential victim: %r", victim)
victims_count += 1 victims_count += 1
@ -107,10 +126,9 @@ class NetworkScanner(object):
LOG.debug("Found max needed victims (%d), stopping scan", max_find) LOG.debug("Found max needed victims (%d), stopping scan", max_find)
break break
if WormConfiguration.tcp_scan_interval:
if WormConfiguration.tcp_scan_interval: # time.sleep uses seconds, while config is in milliseconds
# time.sleep uses seconds, while config is in milliseconds time.sleep(WormConfiguration.tcp_scan_interval / float(1000))
time.sleep(WormConfiguration.tcp_scan_interval/float(1000))
@staticmethod @staticmethod
def _is_any_ip_in_subnet(ip_addresses, subnet_str): def _is_any_ip_in_subnet(ip_addresses, subnet_str):