Пример #1
0
    def __init__(self, logger, interface, pidfile, stdout, stderr):
        """Initialises several things needed to define the daemons behaviour.

        Args:
            logger (logging.Logger): Used for logging messages.
            interface (str): The network interface which should be used. (e.g. eth0)
            pidfile (str): Path of the pidfile, used by the daemon.
            stdout (str): Path of stdout, used by the daemon.
            stderr (str): Path of stderr, used by the daemon.

        Raises:
            DaemonError: Signalises the failure of the daemon.
        """
        super(self.__class__, self).__init__(logger, interface, pidfile, stdout, stderr)
        self.redis = ApateRedis(str(self.network.network), logger)

        # Initialise threads
        self.sniffthread = SelectiveSniffThread(self.interface, self.gateway, self.mac, self.gate_mac, self.redis)
        self.sniffthread.daemon = True
        self.psthread = PubSubThread(self.redis, self.logger)
        self.psthread.daemon = True
        self.arpthread = ARPDiscoveryThread(self.gateway, str(self.network.network))
        self.arpthread.daemon = True
        self.igmpthread = IGMPDiscoveryThread(self.gateway, str(self.network.network), self.ip, self.mac)
        self.igmpthread.daemon = True
Пример #2
0
def toggle_device(mac, ip, enabled):
    from apate_redis import ApateRedis
    if not check_ip(ip) or not check_mac(mac):
        return 27

    try:
        with open(CONFIG_FILE) as config:
            data = json.load(config)
    except ValueError as ve:
        print "Could not parse the configuration file"
        print str(ve)
        return 28
    except IOError as ioe:
        print "An error occurred while trying to open the configuration file"
        print str(ioe)
        return 29

    if 'interface' not in data:
        print "The configuration file does not include all necessary options"
        return 30

    network = get_network(data['interface'], check_ip(ip))
    if not network:
        return 31

    try:
        redis = ApateRedis(network, logging.getLogger('config'))
        if enabled:
            redis.enable_device(mac, ip, network)
        else:
            redis.disable_device(mac, ip, network)
    except:
        return 32

    return 0
Пример #3
0
    def __init__(self, logger, interface, ipv6):
        """Initialises several things needed to define the daemons behaviour.

        Args:
            logger (logging.Logger): Used for logging messages.
            interface (str): The network interface which should be used. (e.g. eth0)
            pidfile (str): Path of the pidfile, used by the daemon.
            stdout (str): Path of stdout, used by the daemon.
            stderr (str): Path of stderr, used by the daemon.
            dns_file (str): Path of file containing the nameservers.

        Raises:
            DaemonError: Signalises the failure of the daemon.
        """
        super(self.__class__, self).__init__()

        self.exit = mp.Event()

        self.interface = interface
        self.logger = logger

        # add redis objects to the ip tuples
        self.ipv6 = ipv6._replace(
            redis=ApateRedis(str(ipv6.network.network), logger))

        # used for thread synchronisation (for waking this thread)
        self.sleeper = threading.Condition()

        self.threads = {}
        # Initialise threads
        self.threads['sniffthread'] = SelectiveIPv6SniffThread(
            self.interface, self.ipv6, self.sleeper, self.logger)
        self.threads['icmpv6thread'] = MulticastPingDiscoveryThread(
            self.interface)
        self.threads['mldv2thread'] = MulticastListenerDiscoveryThread(
            self.interface)
        self.threads['psthread6'] = PubSubThread(self.ipv6, self.logger,
                                                 self.spoof_devices)

        # declare all threads as deamons
        for worker in self.threads:
            self.threads[worker].daemon = True
Пример #4
0
class SelectiveDaemonApp(_DaemonApp):
    """Implements the abstract class _DaemonApp and also implements the selective spoofing mode of Apate.
    The selective spoofing mode requires more resources than the holistic spoofing mode,
    e.g.: the redis-server. This mode only generates packets for existing clients (not every possible client).
    This mode is suitable for bigger networks, as the bottleneck of this mode is virtually only the host discovery.
    """

    __SLEEP = 5
    """int: Defines the time to sleep after packets are sent before they are sent anew."""

    def __init__(self, logger, interface, pidfile, stdout, stderr):
        """Initialises several things needed to define the daemons behaviour.

        Args:
            logger (logging.Logger): Used for logging messages.
            interface (str): The network interface which should be used. (e.g. eth0)
            pidfile (str): Path of the pidfile, used by the daemon.
            stdout (str): Path of stdout, used by the daemon.
            stderr (str): Path of stderr, used by the daemon.

        Raises:
            DaemonError: Signalises the failure of the daemon.
        """
        super(self.__class__, self).__init__(logger, interface, pidfile, stdout, stderr)
        self.redis = ApateRedis(str(self.network.network), logger)

        # Initialise threads
        self.sniffthread = SelectiveSniffThread(self.interface, self.gateway, self.mac, self.gate_mac, self.redis)
        self.sniffthread.daemon = True
        self.psthread = PubSubThread(self.redis, self.logger)
        self.psthread.daemon = True
        self.arpthread = ARPDiscoveryThread(self.gateway, str(self.network.network))
        self.arpthread.daemon = True
        self.igmpthread = IGMPDiscoveryThread(self.gateway, str(self.network.network), self.ip, self.mac)
        self.igmpthread.daemon = True

    def _return_to_normal(self):
        """This method is called when the daemon is stopping.
        First, sends a GARP broadcast request to all clients to tell them the real gateway.
        Then ARP replies for existing clients are sent to the gateway.
        """
        # spoof clients with GARP boradcast request
        sendp(
            Ether(dst=ETHER_BROADCAST) / ARP(op=1, psrc=self.gateway, pdst=self.gateway, hwdst=ETHER_BROADCAST,
                                             hwsrc=self.gate_mac))

        # generate ARP reply packet for every existing client and spoof the gateway
        packets = [Ether(dst=self.gate_mac) / ARP(op=2, psrc=dev[0], pdst=self.gateway, hwsrc=dev[1]) for dev in self.redis.get_devices_values(filter_values=True)]
        sendp(packets)

    def exit(self, signal_number, stack_frame):
        """This method is called from the python-daemon when the daemon is stopping.
        Threads are stopped and clients are despoofed via _return_to_normal().
        """
        self._return_to_normal()
        raise SystemExit()

    def run(self):
        """Starts multiple threads sends out packets to spoof
        all existing clients on the network and the gateway. This packets are sent every __SLEEP seconds.
        The existing clients (device entries) are read from the redis database.

        Threads:
            A SniffThread, which sniffs for incoming ARP packets and adds new devices to the redis db.
            Two HostDiscoveryThread, which are searching for existing devices on the network.
            A PubSubThread, which is listening for redis expiry messages.

        Note:
            First, ARP replies to spoof the gateway entry of existing clients arp cache are generated.
            ARP relpies to spoof the entries of the gateway are generated next.
            Unlike the holistic mode only packets for existing clients are generated.

        """
        self.sniffthread.start()
        self.arpthread.start()
        self.psthread.start()
        self.igmpthread.start()

        # lamda expression to generate arp replies to spoof the clients
        exp1 = lambda dev: Ether(dst=dev[1]) / ARP(op=2, psrc=self.gateway, pdst=dev[0], hwdst=dev[1])

        # lamda expression to generate arp replies to spoof the gateway
        exp2 = lambda dev: Ether(dst=self.gate_mac) / ARP(op=2, psrc=dev[0], pdst=self.gateway, hwdst=self.gate_mac)

        while True:
            # generates packets for existing clients
            # due to the labda expressions p1 and p2 this list comprehension, each iteration generates 2 packets
            # one to spoof the client and one to spoof the gateway
            packets = [p(dev) for dev in self.redis.get_devices_values(filter_values=True) for p in (exp1, exp2)]

            sendp(packets)
            time.sleep(self.__SLEEP)