📄 portscan.c
字号:
*//**** Get a tracker node by either finding one or starting a new one. We may** return NULL, in which case we wait till the next packet.*/static int ps_tracker_get(PS_TRACKER **ht, PS_HASH_KEY *key){ int iRet; *ht = (PS_TRACKER *)sfxhash_find(g_hash, (void *)key); if(!(*ht)) { iRet = sfxhash_add(g_hash, (void *)key, NULL); if(iRet == SFXHASH_OK) { *ht = (PS_TRACKER *)sfxhash_mru(g_hash); if(!(*ht)) return -1; ps_tracker_init(*ht); } else { return -1; } } return 0;}static int ps_tracker_lookup(PS_PKT *ps_pkt, PS_TRACKER **scanner, PS_TRACKER **scanned){ PS_HASH_KEY key; Packet *p; if(!ps_pkt->pkt) return -1; p = (Packet *)ps_pkt->pkt; /* ** Let's lookup the host that is being scanned, taking into account ** the pkt may be reversed. */ if(g_ps_init.detect_scan_type & (PS_TYPE_PORTSCAN | PS_TYPE_DECOYSCAN | PS_TYPE_DISTPORTSCAN)) { key.scanner = 0; if(ps_pkt->reverse_pkt) key.scanned = p->iph->ip_src.s_addr; else key.scanned = p->iph->ip_dst.s_addr; /* ** Get the scanned tracker. */ if(ps_tracker_get(scanned, &key)) return -1; } /* ** Let's lookup the host that is scanning. */ if(g_ps_init.detect_scan_type & PS_TYPE_PORTSWEEP) { key.scanned = 0; if(ps_pkt->reverse_pkt) key.scanner = p->iph->ip_dst.s_addr; else key.scanner = p->iph->ip_src.s_addr; /* ** Get the scanner tracker */ if(ps_tracker_get(scanner, &key)) return -1; } return 0;}/*** NAME** ps_get_proto_index::*//**** This logic finds the index to the proto array based on the** portscan configuration. We need special logic because the ** index of the protocol changes based on the configuration.*/static int ps_get_proto_index(PS_PKT *ps_pkt, int *proto_index, int *proto){ Packet *p; int found = 0; if(!ps_pkt || !ps_pkt->pkt || !proto_index || !proto) return -1; p = (Packet *)ps_pkt->pkt; *proto_index = 0; *proto = 0; if(!found && g_ps_init.detect_scans & PS_PROTO_TCP) { if(p->tcph) { found = 1; *proto = PS_PROTO_TCP; } else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH && p->icmph->code == ICMP_PORT_UNREACH && p->orig_tcph) { found = 1; *proto = PS_PROTO_TCP; } else { (*proto_index)++; } } if(!found && g_ps_init.detect_scans & PS_PROTO_UDP) { if(p->udph) { found = 1; *proto = PS_PROTO_UDP; } else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH && p->icmph->code == ICMP_PORT_UNREACH && p->orig_udph) { found = 1; *proto = PS_PROTO_UDP; } else { (*proto_index)++; } } if(!found && g_ps_init.detect_scans & PS_PROTO_IP) { if(p->iph && !p->icmph) { found = 1; *proto = PS_PROTO_IP; } else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH && p->icmph->code == ICMP_PROT_UNREACH) { found = 1; *proto = PS_PROTO_IP; } else { (*proto_index)++; } } if(!found && g_ps_init.detect_scans & PS_PROTO_ICMP) { if(p->icmph) { found = 1; *proto = PS_PROTO_ICMP; } else { (*proto_index)++; } } if(!found) { *proto = 0; *proto_index = 0; return -1; } return 0;}/*** NAME** ps_proto_update_window::*//**** Update the proto time windows based on the portscan sensitivity** level.*/static int ps_proto_update_window(PS_PROTO *proto, time_t pkt_time){ time_t interval; switch(g_ps_init.sense_level) { case PS_SENSE_LOW: //interval = 15; interval = 60; break; case PS_SENSE_MEDIUM: //interval = 15; interval = 90; break; case PS_SENSE_HIGH: interval = 600; break; default: return -1; } /* ** If we are outside of the window, reset our ps counters. */ if(pkt_time > proto->window) { memset(proto, 0x00, sizeof(PS_PROTO)); proto->window = pkt_time + interval; return 0; } return 0;}/*** NAME** ps_proto_update::*//**** This function updates the PS_PROTO structure.**** @param PS_PROTO pointer to structure to update** @param int number to increment portscan counter** @param u_long IP address of other host** @param u_short port/ip_proto to track** @param time_t time the packet was received. update windows.*/static int ps_proto_update(PS_PROTO *proto, int ps_cnt, int pri_cnt, u_long ip, u_short port, time_t pkt_time){ if(!proto) return 0; /* ** If the ps_cnt is negative, that means we are just taking off ** for valid connection, and we don't want to do anything else, ** like update ip/port, etc. */ if(ps_cnt < 0) { proto->connection_count += ps_cnt; if(proto->connection_count < 0) proto->connection_count = 0; return 0; } /* ** If we are updating a priority cnt, it means we already did the ** unique port and IP on the connection packet. ** ** Priority points are only added for invalid response packets. */ if(pri_cnt) { proto->priority_count += pri_cnt; if(proto->priority_count < 0) proto->priority_count = 0; return 0; } /* ** Do time check first before we update the counters, so if ** we need to reset them we do it before we update them. */ if(ps_proto_update_window(proto, pkt_time)) return -1; /* ** Update ps counter */ proto->connection_count += ps_cnt; if(proto->connection_count < 0) proto->connection_count = 0; if(proto->u_ips != ip) { proto->u_ip_count++; proto->u_ips = ip; } if(proto->low_ip) { if(proto->low_ip > ip) proto->low_ip = ip; } else { proto->low_ip = ip; } if(proto->high_ip) { if(proto->high_ip < ip) proto->high_ip = ip; } else { proto->high_ip = ip; } if(proto->u_ports != port) { proto->u_port_count++; proto->u_ports = port; } if(proto->low_p) { if(proto->low_p > port) proto->low_p = port; } else { proto->low_p = port; } if(proto->high_p) { if(proto->high_p < port) proto->high_p = port; } else { proto->high_p = port; } return 0;}static int ps_update_open_ports(PS_PROTO *proto, unsigned short port){ int iCtr; for(iCtr = 0; iCtr < proto->open_ports_cnt; iCtr++) { if(port == proto->open_ports[iCtr]) return 0; } if(iCtr < (PS_OPEN_PORTS - 1)) { proto->open_ports[iCtr] = port; proto->open_ports_cnt++; if(proto->alerts == PS_ALERT_GENERATED) { proto->alerts = PS_ALERT_OPEN_PORT; } } return 0;} /*** NAME** ps_tracker_update_tcp::*//**** Determine how to update the portscan counter depending on the type** of TCP packet we have.**** We are concerned with three types of TCP packets:** ** - initiating TCP packets (we don't care about flags)** - TCP 3-way handshake packets (we decrement the counter)** - TCP reset packets on unestablished streams.*/static int ps_tracker_update_tcp(PS_PKT *ps_pkt, PS_TRACKER *scanner, PS_TRACKER *scanned, int proto_idx){ Packet *p; Session *ssn; time_t pkt_time; FLOW *flow; p = (Packet *)ps_pkt->pkt; pkt_time = packet_timeofday(); ssn = (Session *)p->ssnptr; flow = (FLOW *)p->flow; /* ** Handle the initiating packet. ** ** If this what stream4 considers to be a valid initiator, then ** we will use the available stream4 information. Otherwise, we ** can just revert to flow and look for initiators and responders. ** ** The "midstream" logic below says that, if we include sessions ** picked up midstream, then we don't care about the MIDSTREAM flag. ** Otherwise, only consider streams not picked up midstream. */ if(ssn) { if((ssn->session_flags & SSNFLAG_SEEN_CLIENT) && !(ssn->session_flags & SSNFLAG_SEEN_SERVER) && (g_include_midstream || !(ssn->session_flags & SSNFLAG_MIDSTREAM))) { if(scanned) { ps_proto_update(&scanned->proto[proto_idx],1,0, p->iph->ip_src.s_addr,p->dp, pkt_time); } if(scanner) { ps_proto_update(&scanner->proto[proto_idx],1,0, p->iph->ip_dst.s_addr,p->dp, pkt_time); } } /* ** Handle the final packet of the three-way handshake. */ else if(p->packet_flags & PKT_STREAM_TWH) { if(scanned) ps_proto_update(&scanned->proto[proto_idx],-1,0,0,0,0); if(scanner) ps_proto_update(&scanner->proto[proto_idx],-1,0,0,0,0); } /* ** RST packet on unestablished streams */ else if((p->packet_flags & PKT_FROM_SERVER) && (p->tcph->th_flags & TH_RST) && (!(p->packet_flags & PKT_STREAM_EST) || (ssn->session_flags & SSNFLAG_MIDSTREAM))) { if(scanned) { ps_proto_update(&scanned->proto[proto_idx],0,1,0,0,0); scanned->priority_node = 1; } if(scanner) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -