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
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
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
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
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
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
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.')
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.')