/** * Check to see if this IPv4 Address should be ignored by the portscan * tracker. * * This checks both the src and dst lists. * * @param pstp portscan tracker * @param sip pointer to the sip in NETWORK byte order * @param dip pointer to the dip in NETWORK byte order * * @return FLOW_SUCCESS if this ip should be ignored, else it should be used */ int flowps_is_ignored_ipv4(PS_TRACKER *pstp, u_int32_t *sip, u_int32_t *dip) { u_int32_t host_sip, host_dip; /**< host ordered addresses */ if(pstp && sip && dip) { if(pstp->config.src_ignore_ipv4) { host_sip = ntohl(*sip); if(ipset_contains(pstp->config.src_ignore_ipv4, &host_sip, NULL, IPV4_FAMILY)) { return FLOW_SUCCESS; } } if(pstp->config.dst_ignore_ipv4) { host_dip = ntohl(*dip); if(ipset_contains(pstp->config.dst_ignore_ipv4, &host_dip, NULL, IPV4_FAMILY)) { return FLOW_SUCCESS; } } return FLOW_DISABLED; } return FLOW_ENULL; }
u_int32_t server_stats_hitcount_ipv4(SERVER_STATS *ssp, u_int8_t ip_proto, u_int32_t address, u_int16_t port) { SERVER_KEY *kp = &s_key; u_int32_t *hitcountp; #ifdef DEBUG u_int32_t hostaddress = ntohl(address); #endif /* DEBUG */ /* OK, IPSETs are acting in HOST ORDER */ FLOWASSERT(ipset_contains(ssp->ipv4_watch, &hostaddress, IPV4_FAMILY)); /* make a key */ kp->address = address; kp->port = port; kp->protocol = ip_proto; hitcountp = (u_int32_t *) sfxhash_find(ssp->ipv4_table, kp); if(hitcountp != NULL) { return *hitcountp; } return 0; }
/** ** Check scanner and scanned ips to see if we can filter them out. */ static int ps_ignore_ip(snort_ip_p scanner, uint16_t scanner_port, snort_ip_p scanned, uint16_t scanned_port) { if (portscan_eval_config->ignore_scanners) { if (ipset_contains(portscan_eval_config->ignore_scanners, scanner, &scanner_port)) return 1; } if(portscan_eval_config->ignore_scanned) { if (ipset_contains(portscan_eval_config->ignore_scanned, scanned, &scanned_port)) return 1; } return 0; }
int server_stats_add_ipv4(SERVER_STATS *ssp, u_int8_t ip_proto, u_int32_t address, u_int16_t port, u_int32_t *retcount) { SERVER_KEY *kp = &s_key; u_int32_t one = 1; u_int32_t *hitcountp = NULL; int ret; #ifdef DEBUG u_int32_t hostaddress = ntohl(address); #endif /* DEBUG */ if(ssp == NULL || retcount == NULL) return FLOW_ENULL; /* calls to this subsystem should only be made if we are really watching this. */ FLOWASSERT(ipset_contains(ssp->ipv4_watch, &hostaddress, IPV4_FAMILY)); /* make the key */ kp->address = address; kp->port = port; kp->protocol = ip_proto; /* find the key, add 1 to it or add a new node to the table */ ret = sfxhash_add(ssp->ipv4_table, kp, &one); switch(ret) { case SFXHASH_NOMEM: /* NOMEM means that we would add it if we could but we're * hard-core out of space. So, just assume we added it. */ case SFXHASH_OK: *retcount = 1; break; case SFXHASH_INTABLE: hitcountp = (u_int32_t *) sfxhash_mru(ssp->ipv4_table); /* never let us wrap around to less hits */ if(!hitcountp) { /* this is an odd error! */ return FLOW_BADJUJU; } else { if((*hitcountp) < SERVER_STATS_MAX_HITCOUNT) { (*hitcountp)++; } } break; } return FLOW_SUCCESS; }
/** * See if we are watching this particular IP * * @param ssp server stats pointer * @param address ipv4 address in NETWORK BYTE ORDER * * @return 1 if this SERVER_STATS is watching this network */ int server_stats_contains(SERVER_STATS *ssp, u_int32_t address) { if(ssp->ipv4_watch) { u_int32_t hostaddress = ntohl(address); if(ipset_contains(ssp->ipv4_watch, &hostaddress, IPV4_FAMILY)) { return FLOW_SUCCESS; } } return FLOW_DISABLED; }
/** ** Check the incoming packet to decide whether portscan detection cares ** about this packet. We try to ignore as many packets as possible. */ static int ps_filter_ignore(PS_PKT *ps_pkt) { Packet *p; int reverse_pkt = 0; snort_ip_p scanner, scanned; p = (Packet *)ps_pkt->pkt; if(!IPH_IS_VALID(p)) return 1; if(p->tcph) { if(!(portscan_eval_config->detect_scans & PS_PROTO_TCP)) return 1; /* ** This is where we check all of snort's flags for different ** TCP session scenarios. The checks cover: ** ** - dropping packets in established sessions, but not the ** TWH packet. ** - dropping the SYN/ACK packet from the server on a valid ** connection (we'll catch the TWH later if it happens). */ /* ** Ignore packets that are already part of an established TCP ** stream. */ if(((p->packet_flags & (PKT_STREAM_EST | PKT_STREAM_TWH)) == PKT_STREAM_EST) && !(p->tcph->th_flags & TH_RST)) { return 1; } /* ** Ignore the server's initial response, unless it's to RST ** the connection. */ /* if(!(p->tcph->th_flags & TH_RST) && !(p->packet_flags & (PKT_STREAM_EST)) && (p->packet_flags & PKT_FROM_SERVER)) { return 1; } */ } else if(p->udph) { if(!(portscan_eval_config->detect_scans & PS_PROTO_UDP)) return 1; } else if(p->icmph) { if(p->icmph->type != ICMP_DEST_UNREACH && !(portscan_eval_config->detect_scans & PS_PROTO_ICMP)) { return 1; } } else { if(!(portscan_eval_config->detect_scans & PS_PROTO_IP)) return 1; } /* ** Check if the packet is reversed */ if((p->packet_flags & PKT_FROM_SERVER)) { reverse_pkt = 1; } else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH) { reverse_pkt = 1; } else if (p->udph && p->ssnptr && stream_api && stream_api->version >= STREAM_API_VERSION5) { if (stream_api->get_packet_direction(p) & PKT_FROM_SERVER) reverse_pkt = 1; } scanner = GET_SRC_IP(p); scanned = GET_DST_IP(p); if(reverse_pkt) { if(ps_ignore_ip(scanned, p->dp, scanner, p->sp)) return 1; } else { if(ps_ignore_ip(scanner, p->sp, scanned, p->dp)) return 1; } ps_pkt->reverse_pkt = reverse_pkt; if(portscan_eval_config->watch_ip) { if(ipset_contains(portscan_eval_config->watch_ip, scanner, &(p->sp))) return 0; if(ipset_contains(portscan_eval_config->watch_ip, scanned, &(p->dp))) return 0; return 1; } return 0; }
// ----------------------------- void test_ipset() { int i,k; IPSET * ipset, * ipset6; IPSET * ipset_copyp, * ipset6_copyp; unsigned ipaddress, mask; unsigned short mask6[8]; unsigned short ipaddress6[8]; unsigned port_lo, port_hi; PORTSET portset; printf("IPSET testing\n"); ipset = ipset_new(IPV4_FAMILY); ipset6 = ipset_new(IPV6_FAMILY); srand( time(0) ); for(i=0;i<MAXIP;i++) { if( i % 2 ) { ipaddress = rand() * rand(); mask = 0xffffff00; port_lo = rand(); port_hi = rand() % 5 + port_lo; portset_init(&portset); portset_add(&portset, port_lo, port_hi); ipset_add( ipset, &ipaddress, &mask, &portset, 0, IPV4_FAMILY ); //class C cidr blocks if( !ipset_contains( ipset, &ipaddress, &port_lo, IPV4_FAMILY ) ) printf("error with ipset_contains\n"); } else { for(k=0;k<8;k++) ipaddress6[k] = (char) (rand() % (1<<16)); for(k=0;k<8;k++) mask6[k] = 0xffff; port_lo = rand(); port_hi = rand() % 5 + port_lo; portset_init(&portset); portset_add(&portset, port_lo, port_hi); ipset_add( ipset6, ipaddress6, mask6, &portset, 0, IPV6_FAMILY ); if( !ipset_contains( ipset6, &ipaddress6, &port_lo, IPV6_FAMILY ) ) printf("error with ipset6_contains\n"); } } ipset_copyp = ipset_copy( ipset ); ipset6_copyp = ipset_copy( ipset6 ); printf("-----IP SET-----\n"); ipset_print( ipset ); printf("\n"); printf("-----IP SET6-----\n"); ipset_print( ipset6 ); printf("\n"); printf("-----IP SET COPY -----\n"); ipset_print( ipset_copyp ); printf("\n"); printf("-----IP SET6 COPY -----\n"); ipset_print( ipset6_copyp ); printf("\n"); printf("IP set testing completed\n"); }