Beispiel #1
0
class Sniffer(object):
    "Channel hopping, packet sniffing, parsing and finally storing"

    def __init__(self,
                 db,
                 interface,
                 related_interface,
                 sniffer_name,
                 enable_hopping,
                 use_24=True,
                 use_pop5=False):
        self.db = db
        self.sniffer_name = sniffer_name
        self.interface = interface
        self.enable_hopping = enable_hopping

        # Check interface existance
        if not self._iface_exists(interface):
            print "Exiting: Interface %s doesn't exist" % interface
            sys.exit(1)

        if related_interface and not self._iface_exists(related_interface):
            print "Exiting: Related interface %s doesn't exist" % interface
            sys.exit(1)

        # Logging
        header = 'SNIFF'
        if sniffer_name:
            header += '_' + sniffer_name
        self.log = Log(self.db, use_stdout=True, header=header)

        # Submodules
        self.packet_parser = PacketParser(self.log)
        self.hopper = Hopper(self.log, interface, related_interface)
        ret = self.hopper.configure(use_24=use_24, use_pop5=use_pop5)
        if ret is False:
            sys.exit(1)

        config.conf.sniff_promisc = 0
        self.log.info("Promiscuous mode disabled")

        self.watchdog = WatchDog(interval=20)

    def _iface_exists(self, iface_name):
        "Check if interface exists"
        path = '/sys/class/net'
        iface_path = os.path.join(path, iface_name)
        try:
            _ = os.stat(iface_path)
            return True
        except OSError:
            return False

    def run(self):
        "Sniffer main loop"

        begin = time()
        pkts_all = 0

        sniff_begin = time()
        stat_prev = sniff_begin
        stat_every = 3  # seconds
        while True:
            start = time()

            # This catches KeyboardInterrupt,
            # TODO: Disable this catching + Probably hop on another thread and use prn argument.
            # But then - you'd have watchdog problems.
            pkts = sendrecv.sniff(iface=self.interface, count=20, timeout=0.1)
            pkts_all += len(pkts)
            for pkt in pkts:
                data = self.packet_parser.parse(pkt)
                if data is None:
                    continue

                data['ch'] = self.hopper.channel_number
                data['sniffer'] = self.sniffer_name

                if ('PROBE_REQ' in data['tags'] or 'PROBE_RESP' in data['tags']
                        or 'ASSOC_REQ' in data['tags']
                        or 'DISASS' in data['tags']):
                    # Increase karma when client traffic is detected
                    self.hopper.increase_karma()

                data['tags'] = list(data['tags'])
                self.db.frames.add(data)
            now = time()
            took = now - start

            if stat_prev + stat_every < now:
                took = time() - sniff_begin
                print "STAT: pkts=%d t_total=%.2fs pps=%.2f swipes=%d avg_swipe_t=%.2f cur_ch=%d" % (
                    pkts_all,
                    took,
                    pkts_all / took,
                    self.hopper.swipes_total,
                    took / (self.hopper.swipes_total + 0.001),
                    self.hopper.channel_number,
                )
                stat_prev = now

            if self.enable_hopping:
                ret = self.hopper.karmic_hop()
                if ret is False:
                    break

            self.watchdog.dontkillmeplease()
Beispiel #2
0
class PluginManager:
    def __init__(self, config: ConfigurationManager, base=BasePlugin):
        self.base = base
        self.config = config
        self.failed = {}
        self._seen_classes = set()
        self._plugins = {}
        self._activated_plugins = set()
        self._deactivated_plugins = set()
        self._resolved = False
        self._overrides = set()
        self._override_cache = set()
        self._packet_parser = PacketParser(self.config)

    def list_plugins(self):
        return self._plugins

    @asyncio.coroutine
    def do(self, protocol, action: str, packet: dict):
        """
        Calls an action on all loaded plugins
        """
        try:
            if ("on_%s" % action) in self._overrides:
                packet = yield from self._packet_parser.parse(packet)
                send_flag = True
                for plugin in self._plugins.values():
                    p = getattr(plugin, "on_%s" % action)
                    if not (yield from p(packet, protocol)):
                        send_flag = False
                return send_flag
            else:
                return True
        except Exception:
            print("Exception encountered in plugin.")
            traceback.print_exc()
            return True

    def load_from_path(self, plugin_path: pathlib.Path):
        blacklist = ["__init__", "__pycache__"]
        loaded = set()
        for file in plugin_path.iterdir():
            if file.stem in blacklist:
                continue
            if (file.suffix == ".py" or file.is_dir()) and str(
                    file) not in loaded:
                try:
                    loaded.add(str(file))
                    self.load_plugin(file)
                except (SyntaxError, ImportError) as e:
                    self.failed[file.stem] = str(e)
                    print(e)
                except FileNotFoundError:
                    print("File not found")

    @staticmethod
    def _load_module(file_path: pathlib.Path):
        """
        Attempts to load a module, either from a straight python file or from
        a python package, by appending __init__.py to the end of the path if it
        is a directory.
        """
        if file_path.is_dir():
            file_path /= '__init__.py'
        if not file_path.exists():
            raise FileNotFoundError("{0} doesn't exist.".format(str(file_path)))
        name = "plugins.%s" % file_path.stem
        loader = importlib.machinery.SourceFileLoader(name, str(file_path))
        module = loader.load_module(name)
        return module

    def load_plugin(self, plugin_path: pathlib.Path):
        module = self._load_module(plugin_path)
        classes = self.get_classes(module)
        for candidate in classes:
            self._seen_classes.add(candidate)

    def get_classes(self, module: ModuleType):
        """
        Uses the inspect module to find all classes in a given module that
        are subclassed from `self.base`, but are not actually `self.base`.
        """
        class_list = []
        for _, obj in inspect.getmembers(module):
            if inspect.isclass(obj):
                if issubclass(obj, self.base) and obj is not self.base:
                    obj.config = self.config
                    class_list.append(obj)

        return class_list

    def load_plugins(self, plugins: list):
        for plugin in plugins:
            self.load_plugin(plugin)

    def resolve_dependencies(self):
        """
        Resolves dependencies from self._seen_classes through a very simple
        topological sort. Raises ImportError if there is an unresolvable
        dependency, otherwise it instantiates the class and puts it in
        self._plugins.
        """
        deps = {x.name: set(x.depends) for x in self._seen_classes}
        classes = {x.name: x for x in self._seen_classes}
        while len(deps) > 0:
            ready = [x for x, d in deps.items() if len(d) == 0]
            for name in ready:
                self._plugins[name] = classes[name]()
                del deps[name]
            for name, depends in deps.items():
                to_load = depends & set(self._plugins.keys())
                deps[name] = deps[name].difference(set(self._plugins.keys()))
                for plugin in to_load:
                    classes[name].plugins[plugin] = self._plugins[plugin]
            if len(ready) == 0:
                raise ImportError("Unresolved dependencies found.")
        self._resolved = True

    @asyncio.coroutine
    def get_overrides(self):
        if self._override_cache is self._activated_plugins:
            return self._overrides
        else:
            overrides = set()
            for plugin in self._activated_plugins:
                override = yield from detect_overrides(BasePlugin, plugin)
                overrides.update({x for x in override})
            self._overrides = overrides
            self._override_cache = self._activated_plugins
            return overrides

    def activate_all(self):
        for plugin in self._plugins.values():
            print(plugin)
            plugin.activate()
            self._activated_plugins.add(plugin)

    def deactivate_all(self):
        for plugin in self._plugins.values():
            print("Deactivating")
            plugin.deactivate()
Beispiel #3
0
class Sniffer(object):
    "Channel hopping, packet sniffing, parsing and finally storing"

    def __init__(self, db, interface, related_interface, sniffer_name, enable_hopping,
                 use_24=True, use_pop5=False):
        self.db = db
        self.sniffer_name = sniffer_name
        self.interface = interface
        self.enable_hopping = enable_hopping

        # Check interface existance
        if not self._iface_exists(interface):
            print "Exiting: Interface %s doesn't exist" % interface
            sys.exit(1)

        if related_interface and not self._iface_exists(related_interface):
            print "Exiting: Related interface %s doesn't exist" % interface
            sys.exit(1)

        # Logging
        header = 'SNIFF'
        if sniffer_name:
            header += '_' + sniffer_name
        self.log = Log(self.db, use_stdout=True, header=header)

        # Submodules
        self.packet_parser = PacketParser(self.log)
        self.hopper = Hopper(self.log, interface, related_interface)
        ret = self.hopper.configure(use_24=use_24, use_pop5=use_pop5)
        if ret is False:
            sys.exit(1)

        config.conf.sniff_promisc = 0
        self.log.info("Promiscuous mode disabled")

        self.watchdog = WatchDog(interval=20)


    def _iface_exists(self, iface_name):
        "Check if interface exists"
        path = '/sys/class/net'
        iface_path = os.path.join(path, iface_name)
        try:
            _ = os.stat(iface_path)
            return True
        except OSError:
            return False

    def run(self):
        "Sniffer main loop"

        begin = time()
        pkts_all = 0

        sniff_begin = time()
        stat_prev = sniff_begin
        stat_every = 3 # seconds
        while True:
            start = time()

            # This catches KeyboardInterrupt,
            # TODO: Disable this catching + Probably hop on another thread and use prn argument.
            # But then - you'd have watchdog problems.
            pkts = sendrecv.sniff(iface=self.interface, count=20, timeout=0.1)
            pkts_all += len(pkts)
            for pkt in pkts:
                data = self.packet_parser.parse(pkt)
                if data is None:
                    continue

                data['ch'] = self.hopper.channel_number
                data['sniffer'] = self.sniffer_name

                if ('PROBE_REQ' in data['tags'] or
                    'PROBE_RESP' in data['tags'] or
                    'ASSOC_REQ' in data['tags'] or
                    'DISASS' in data['tags']):
                    # Increase karma when client traffic is detected
                    self.hopper.increase_karma()

                data['tags'] = list(data['tags'])
                self.db.frames.add(data)
            now = time()
            took = now - start

            if stat_prev + stat_every < now:
                took = time() - sniff_begin
                print "STAT: pkts=%d t_total=%.2fs pps=%.2f swipes=%d avg_swipe_t=%.2f cur_ch=%d" % (
                    pkts_all, took,
                    pkts_all / took,
                    self.hopper.swipes_total,
                    took/(self.hopper.swipes_total + 0.001),
                    self.hopper.channel_number,
                )
                stat_prev = now

            if self.enable_hopping:
                ret = self.hopper.karmic_hop()
                if ret is False:
                    break

            self.watchdog.dontkillmeplease()