2015-08-30 15:27:35 +08:00
|
|
|
import logging
|
2018-02-07 01:56:25 +08:00
|
|
|
import time
|
|
|
|
|
2015-11-30 20:11:19 +08:00
|
|
|
from config import WormConfiguration
|
2016-07-15 21:54:46 +08:00
|
|
|
from info import local_ips, get_ips_from_interfaces
|
2015-11-30 16:56:20 +08:00
|
|
|
from range import *
|
2018-02-07 01:56:25 +08:00
|
|
|
from . import HostScanner
|
2015-08-30 15:27:35 +08:00
|
|
|
|
|
|
|
__author__ = 'itamar'
|
|
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
SCAN_DELAY = 0
|
|
|
|
|
2015-11-26 21:48:47 +08:00
|
|
|
|
2015-08-30 15:27:35 +08:00
|
|
|
class NetworkScanner(object):
|
|
|
|
def __init__(self):
|
|
|
|
self._ip_addresses = None
|
|
|
|
self._ranges = None
|
|
|
|
|
|
|
|
def initialize(self):
|
2018-02-07 01:56:25 +08:00
|
|
|
"""
|
|
|
|
Set up scanning based on configuration
|
|
|
|
FixedRange -> Reads from range_fixed field in configuration
|
|
|
|
otherwise, takes a range from every IP address the current host has.
|
|
|
|
:return:
|
|
|
|
"""
|
2015-08-30 15:27:35 +08:00
|
|
|
# get local ip addresses
|
2015-09-29 22:58:06 +08:00
|
|
|
self._ip_addresses = local_ips()
|
2015-08-30 15:27:35 +08:00
|
|
|
|
|
|
|
if not self._ip_addresses:
|
|
|
|
raise Exception("Cannot find local IP address for the machine")
|
|
|
|
|
|
|
|
LOG.info("Found local IP addresses of the machine: %r", self._ip_addresses)
|
2015-09-30 20:05:30 +08:00
|
|
|
# for fixed range, only scan once.
|
|
|
|
if WormConfiguration.range_class is FixedRange:
|
2018-02-07 01:56:25 +08:00
|
|
|
self._ranges = [WormConfiguration.range_class(fixed_addresses=WormConfiguration.range_fixed)]
|
2015-09-30 20:05:30 +08:00
|
|
|
else:
|
|
|
|
self._ranges = [WormConfiguration.range_class(ip_address)
|
|
|
|
for ip_address in self._ip_addresses]
|
2016-07-15 21:54:46 +08:00
|
|
|
if WormConfiguration.local_network_scan:
|
|
|
|
self._ranges += [FixedRange([ip_address for ip_address in get_ips_from_interfaces()])]
|
2015-08-30 15:27:35 +08:00
|
|
|
LOG.info("Base local networks to scan are: %r", self._ranges)
|
|
|
|
|
2016-07-04 15:44:57 +08:00
|
|
|
def get_victim_machines(self, scan_type, max_find=5, stop_callback=None):
|
2015-08-30 15:27:35 +08:00
|
|
|
assert issubclass(scan_type, HostScanner)
|
|
|
|
|
|
|
|
scanner = scan_type()
|
|
|
|
victims_count = 0
|
|
|
|
|
2016-08-20 22:58:59 +08:00
|
|
|
for net_range in self._ranges:
|
|
|
|
LOG.debug("Scanning for potential victims in the network %r", net_range)
|
|
|
|
for victim in net_range:
|
2016-07-04 15:44:57 +08:00
|
|
|
if stop_callback and stop_callback():
|
|
|
|
LOG.debug("Got stop signal")
|
|
|
|
break
|
|
|
|
|
2015-08-30 15:27:35 +08:00
|
|
|
# skip self IP address
|
|
|
|
if victim.ip_addr in self._ip_addresses:
|
|
|
|
continue
|
|
|
|
|
2016-09-21 16:35:41 +08:00
|
|
|
# skip IPs marked as blocked
|
|
|
|
if victim.ip_addr in WormConfiguration.blocked_ips:
|
|
|
|
LOG.info("Skipping %s due to blacklist" % victim)
|
|
|
|
continue
|
|
|
|
|
2015-08-30 15:27:35 +08:00
|
|
|
LOG.debug("Scanning %r...", victim)
|
|
|
|
|
|
|
|
# if scanner detect machine is up, add it to victims list
|
|
|
|
if scanner.is_host_alive(victim):
|
2015-10-08 18:30:36 +08:00
|
|
|
LOG.debug("Found potential victim: %r", victim)
|
2015-08-30 15:27:35 +08:00
|
|
|
victims_count += 1
|
|
|
|
yield victim
|
|
|
|
|
|
|
|
if victims_count >= max_find:
|
|
|
|
LOG.debug("Found max needed victims (%d), stopping scan", max_find)
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
if SCAN_DELAY:
|
|
|
|
time.sleep(SCAN_DELAY)
|