Beispiel #1
0
    def _pre_check(self, nfqueue):
        if (not self.ddos_engine_enabled
                and nfqueue.get_mark() == IP_PROXY_DROP):
            Log.debug(
                'packet fast dropped from ip proxy | ddos engine disabled')
            nfqueue.drop()

        elif (not self.inspection_enabled):
            self.forward_packet(nfqueue)
        else:
            return True  # marking for inspection
Beispiel #2
0
    def _threshhold_exceeded(self, initial, count):
        protocol_src_limit = self._IPS.connection_limits[self._packet.protocol]
        elapsed_time = self._packet.timestamp - initial
        if (elapsed_time < 2): return False

        connections_per_second = count / elapsed_time
        if (connections_per_second < protocol_src_limit): return False

        # host is now considered active DDOS
        Log.debug(f'CPS: {connections_per_second}')
        return True
Beispiel #3
0
    def _threshhold_exceeded(self, tracked_ip, packet):
        protocol_src_limit = self._IPS.connection_limits[packet.protocol]
        elapsed_time = packet.timestamp - tracked_ip['initial']
        if (elapsed_time < 2): return False

        if (tracked_ip['count'] / elapsed_time < protocol_src_limit):
            return False

        # host is now considered active DDOS
        Log.debug('CPS: {}'.format(tracked_ip['count'] / elapsed_time))

        return True
Beispiel #4
0
    def _threshhold_exceeded(self, tracked_ip, packet):
        elapsed_time = packet.timestamp - tracked_ip['initial']
        if (elapsed_time < 2): return False

        protocol_src_limit = self._IPS.connection_limits[packet.protocol]
        if (tracked_ip['count'] / elapsed_time < protocol_src_limit):
            return False

        # host is now marked as engaging in active d/dos attack.
        Log.debug('CPS: {}'.format(tracked_ip['count'] / elapsed_time))

        return True
Beispiel #5
0
    def _ddos_timeout(self, tracked_ip, ddos_tracker):
        # if marked as an active ddos host, will timeout the conn
        # since we will be dropping all subsequent conn attempts at the kernel level
        if self.active_ddos_hosts.pop(tracked_ip, None): return 'break'

        # if tracked ip hasnt been seen for 10 seconds, it will be removed from the ddos tracker and thread will close
        tracked_connection = ddos_tracker.get(tracked_ip, None)
        last_seen = tracked_connection.get('last_seen')
        if (time.time() - last_seen >= 10):
            ddos_tracker.pop(tracked_ip)
            Log.debug(f'DDOS TIMED OUT CONN: {tracked_ip}')

            return 'break'

        return 5.1
Beispiel #6
0
    def _ddos_detected(self, ddos_tracker, packet):
        tracked_ip = ddos_tracker.get(packet.conn.tracked_ip, None)
        if (not tracked_ip or fast_time() - tracked_ip['last_seen'] > 15):
            self._add_to_tracker(ddos_tracker, packet, engine=IPS.DDOS)

        else:
            tracked_ip['count'] += 1
            tracked_ip['last_seen'] = packet.timestamp

            # if conn limit exceeded and host is not already marked, returns active ddos and add ip to tracker
            if self._threshhold_exceeded(tracked_ip, packet):
                Log.debug(f'ACTIVE BLOCK: {packet.conn.tracked_ip}')

                # this is to supress log entries for ddos hosts that are being detected by the engine since there is a delay
                # between detection and kernel offload or some packets are already in queue
                if (packet.conn.tracked_ip not in self._IPS.fw_rules):
                    self._IPS.fw_rules[
                        packet.conn.tracked_ip] = packet.timestamp

                    return True

        return False
Beispiel #7
0
    def _portscan_inspect(self, IPS_IDS, packet):
        pscan = self.pscan_tracker[packet.protocol]
        with pscan.lock:
            initial_block, active_scanner, pre_detection_logging = self._portscan_detect(
                pscan.tracker, packet)

        if (not active_scanner):
            Log.debug(
                f'PROXY ACCEPT | {packet.src_ip}:{packet.src_port} > {packet.dst_ip}:{packet.dst_port}.'
            )
            IPS_IDS.forward_packet(packet.nfqueue)

            return

        if (IPS_IDS.ids_mode):
            IPS_IDS.forward_packet(packet.nfqueue)
            block_status = IPS.LOGGED

        elif (IPS_IDS.portscan_prevention):
            packet.nfqueue.drop()

            # if rejection is enabled on top of prevention port uncreachable packets will be sent back to the scanner.
            if (IPS_IDS.portscan_reject):
                self._portscan_reject(pre_detection_logging, packet,
                                      initial_block)

            # if initial block is not set then the current host has already been effectively blocked and does not need
            # to do anything beyond this point.
            if (not initial_block): return

            block_status = self._get_block_status(pre_detection_logging,
                                                  packet.protocol)

        Log.debug(
            f'PROXY INITIAL SCANNER | {block_status.name} | {packet.src_ip}:{packet.src_port} > {packet.dst_ip}:{packet.dst_port}.'
        )

        # NOTE: i think this is stupid. this would effectivly block all portscan logging while passive blocking is
        # active, right???? if that is the case, we need to figure out a different way to deal with this. i think this
        # was to ensure ddos wasnt logged as portscan first, but this doesnt soudn liek a good way to do this anymore.
        if (not IPS_IDS.fw_rules):
            scan_info = IPS_SCAN_RESULTS(initial_block, active_scanner,
                                         block_status)
            Log.log(packet, scan_info, engine=IPS.PORTSCAN)

        else:  # NOTE: for testing purposes only
            Log.debug(
                'ACTIVE DDOS WHEN ATTEMPTING TO LOG PORTSCAN, LOG HAULTED.')
Beispiel #8
0
    def _portscan_inspect(self, packet):
        # TODO: optimize _IPS reference please! :)
        pscan = self.pscan_tracker[packet.protocol]
        with pscan.lock:
            initial_block, active_scanner, pre_detection_logging = self._portscan_detect(
                pscan.tracker, packet)

        if (not active_scanner):
            Log.debug(
                f'PROXY ACCEPT | {packet.src_ip}:{packet.src_port} > {packet.dst_ip}:{packet.dst_port}.'
            )
            self._IPS.forward_packet(packet.nfqueue)

            return

        if (self._IPS.ids_mode):
            self._IPS.forward_packet(packet.nfqueue)
            block_status = IPS.LOGGED

        elif (self._IPS.portscan_prevention):
            packet.nfqueue.drop()

            # if rejection is enabled on top of prevention port uncreachable packets will be sent back to the scanner.
            if (self._IPS.portscan_reject):
                self._portscan_reject(pre_detection_logging, packet,
                                      initial_block)

            # if initial block is not set then the current host has already been effectively blocked and does not need
            # to do anything beyond this point.
            if (not initial_block): return

            block_status = self._get_block_status(pre_detection_logging,
                                                  packet.protocol)

        Log.debug(
            f'PROXY INITIAL SCANNER | {block_status.name} | {packet.src_ip}:{packet.src_port} > {packet.dst_ip}:{packet.dst_port}.'
        )

        if (not self._IPS.fw_rules):
            scan_info = IPS_SCAN_RESULTS(initial_block, active_scanner,
                                         block_status)
            Log.log(packet, scan_info, engine=IPS.PORTSCAN)

        else:  # NOTE: for testing purposes only
            Log.debug(
                'ACTIVE DDOS WHEN ATTEMPTING TO LOG PORTSCAN, LOG HAULTED.')