00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sys/types.h>
00022 #ifndef WIN32
00023 #include <sys/socket.h>
00024 #include <netinet/in.h>
00025 #include <arpa/inet.h>
00026 #endif
00027
00028 #include "decode.h"
00029 #include "plugbase.h"
00030 #include "generators.h"
00031 #include "event_wrapper.h"
00032 #include "util.h"
00033 #include "ipobj.h"
00034 #include "checksum.h"
00035 #include "packet_time.h"
00036 #include "snort.h"
00037 #include "sfthreshold.h"
00038
00039 #include "portscan.h"
00040
00041 #ifdef GIDS
00042 #include "spp_stickydrop.h"
00043 #endif
00044
00045 #define DELIMITERS " \t\n"
00046 #define TOKEN_ARG_BEGIN "{"
00047 #define TOKEN_ARG_END "}"
00048
00049 #define PROTO_BUFFER_SIZE 256
00050
00051 extern PV pv;
00052 extern char *file_name;
00053 extern int file_line;
00054
00055 #ifdef GIDS
00056
00057 extern SDtimeout sdt;
00058 #endif
00059
00060 static int g_print_tracker = 0;
00061 static u_char g_logpath[256];
00062 static FILE *g_logfile = NULL;
00063 static Packet *g_tmp_pkt;
00064
00065 int g_include_midstream = 0;
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 static int PortscanPacketInit(void)
00084 {
00085 const char mac_addr[] = "MACDAD";
00086 Packet *p;
00087
00088 p = (Packet *)calloc(1, sizeof(Packet));
00089 if(!p)
00090 return -1;
00091
00092 p->pkth = calloc(1, sizeof(struct pcap_pkthdr) + ETHERNET_HEADER_LEN + 2 +
00093 IP_MAXPACKET);
00094
00095 if(!p->pkth)
00096 return -1;
00097
00098 p->pkth = (struct pcap_pkthdr *)(((u_char *)p->pkth));
00099
00100
00101 p->pkt = ((u_char *)p->pkth + sizeof(SnortPktHeader) + 2);
00102 p->eh = (EtherHdr *)p->pkt;
00103 p->iph = (IPHdr *)(((u_char *)p->eh) + ETHERNET_HEADER_LEN);
00104 p->data = ((u_char *)p->iph) + sizeof(IPHdr);
00105
00106
00107
00108
00109 p->eh->ether_type = htons(0x0800);
00110 memcpy(p->eh->ether_dst, mac_addr, 6);
00111 memcpy(p->eh->ether_src, mac_addr, 6);
00112
00113 g_tmp_pkt = p;
00114
00115 return 0;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 static int MakeProtoInfo(PS_PROTO *proto, u_char *buffer, u_int *total_size)
00138 {
00139 unsigned char *ip1;
00140 unsigned char *ip2;
00141 int dsize;
00142
00143 if(!total_size || !buffer)
00144 return -1;
00145
00146 dsize = (IP_MAXPACKET - *total_size);
00147
00148 if(dsize < PROTO_BUFFER_SIZE)
00149 return -1;
00150
00151 ip1 = (char *)&proto->low_ip;
00152 ip2 = (char *)&proto->high_ip;
00153
00154 if(proto->alerts == PS_ALERT_PORTSWEEP ||
00155 proto->alerts == PS_ALERT_PORTSWEEP_FILTERED)
00156 {
00157 dsize = snprintf((char *)buffer, PROTO_BUFFER_SIZE,
00158 "Priority Count: %d\n"
00159 "Connection Count: %d\n"
00160 "IP Count: %d\n"
00161 "Scanned IP Range: %d.%d.%d.%d:%d.%d.%d.%d\n"
00162 "Port/Proto Count: %d\n"
00163 "Port/Proto Range: %d:%d\n",
00164 proto->priority_count,
00165 proto->connection_count,
00166 proto->u_ip_count,
00167 ip1[0],ip1[1],ip1[2],ip1[3],
00168 ip2[0],ip2[1],ip2[2],ip2[3],
00169 proto->u_port_count,
00170 proto->low_p,
00171 proto->high_p);
00172 }
00173 else
00174 {
00175 dsize = snprintf((char *)buffer, PROTO_BUFFER_SIZE,
00176 "Priority Count: %d\n"
00177 "Connection Count: %d\n"
00178 "IP Count: %d\n"
00179 "Scanner IP Range: %d.%d.%d.%d:%d.%d.%d.%d\n"
00180 "Port/Proto Count: %d\n"
00181 "Port/Proto Range: %d:%d\n",
00182 proto->priority_count,
00183 proto->connection_count,
00184 proto->u_ip_count,
00185 ip1[0],ip1[1],ip1[2],ip1[3],
00186 ip2[0],ip2[1],ip2[2],ip2[3],
00187 proto->u_port_count,
00188 proto->low_p,
00189 proto->high_p);
00190 }
00191
00192 *total_size += dsize;
00193
00194
00195
00196
00197 g_tmp_pkt->dsize = dsize;
00198
00199 return 0;
00200 }
00201
00202 static int LogPortscanAlert(Packet *p, char *msg, u_int32_t event_id,
00203 u_int32_t event_ref, u_int32_t gen_id, u_int32_t sig_id)
00204 {
00205 char timebuf[TIMEBUF_SIZE];
00206 u_long src_addr = 0;
00207 u_long dst_addr = 0;
00208
00209 if(!p->iph)
00210 return -1;
00211
00212
00213 if ( p->iph )
00214 {
00215 src_addr = p->iph->ip_src.s_addr;
00216 dst_addr = p->iph->ip_dst.s_addr;
00217 }
00218
00219 if( !sfthreshold_test(gen_id, sig_id, src_addr, dst_addr, p->pkth->ts.tv_sec) )
00220 {
00221 return 0;
00222 }
00223
00224 ts_print((struct timeval *)&p->pkth->ts, timebuf);
00225
00226 fprintf(g_logfile, "Time: %s\n", timebuf);
00227
00228 if(event_id)
00229 fprintf(g_logfile, "event_id: %u\n", event_id);
00230 else
00231 fprintf(g_logfile, "event_ref: %u\n", event_ref);
00232
00233 fprintf(g_logfile, "%s ", inet_ntoa(p->iph->ip_src));
00234 fprintf(g_logfile, "-> %s %s\n", inet_ntoa(p->iph->ip_dst), msg);
00235 fprintf(g_logfile, "%.*s\n", p->dsize, p->data);
00236
00237 fflush(g_logfile);
00238
00239 return 0;
00240 }
00241
00242 static int GeneratePSSnortEvent(Packet *p,u_int32_t gen_id,u_int32_t sig_id,
00243 u_int32_t sig_rev, u_int32_t class, u_int32_t priority, char *msg)
00244 {
00245 unsigned int event_id;
00246
00247 event_id = GenerateSnortEvent(p,gen_id,sig_id,sig_rev,class,priority,msg);
00248
00249 if(g_logfile)
00250 LogPortscanAlert(p, msg, event_id, 0, gen_id, sig_id);
00251
00252 return event_id;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 static int GenerateOpenPortEvent(Packet *p, u_int32_t gen_id, u_int32_t sig_id,
00268 u_int32_t sig_rev, u_int32_t class, u_int32_t pri,
00269 u_int32_t event_ref, struct timeval *event_time, char *msg)
00270 {
00271 Event event;
00272
00273
00274
00275
00276
00277
00278 if(!event_ref)
00279 return 0;
00280
00281
00282 sfthreshold_reset();
00283
00284 SetEvent(&event, gen_id, sig_id, sig_rev, class, pri, event_ref);
00285
00286
00287 event.ref_time.tv_sec = event_time->tv_sec;
00288 event.ref_time.tv_usec = event_time->tv_usec;
00289
00290 if(p)
00291 {
00292
00293
00294
00295
00296
00297 if( !sfthreshold_test(gen_id, sig_id, p->iph->ip_src.s_addr,
00298 p->iph->ip_dst.s_addr, p->pkth->ts.tv_sec) )
00299 {
00300 return 0;
00301 }
00302
00303 CallLogFuncs(p,msg,NULL,&event);
00304 }
00305
00306 if(g_logfile)
00307 LogPortscanAlert(p, msg, 0, event_ref, gen_id, sig_id);
00308
00309 return event.event_id;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 static int MakeOpenPortInfo(PS_PROTO *proto, u_char *buffer, u_int *total_size,
00322 void *user)
00323 {
00324 int dsize;
00325
00326 if(!total_size || !buffer)
00327 return -1;
00328
00329 dsize = (IP_MAXPACKET - *total_size);
00330
00331 if(dsize < PROTO_BUFFER_SIZE)
00332 return -1;
00333
00334 dsize = snprintf((char *)buffer, PROTO_BUFFER_SIZE,
00335 "Open Port: %u\n", *((unsigned short *)user));
00336
00337 *total_size += dsize;
00338
00339
00340
00341
00342 g_tmp_pkt->dsize = dsize;
00343
00344 return 0;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 static int MakePortscanPkt(PS_PKT *ps_pkt, PS_PROTO *proto, int proto_type,
00360 void *user)
00361 {
00362 Packet *p;
00363 unsigned long tmp_addr;
00364 unsigned int hlen;
00365 unsigned int ip_size = 0;
00366
00367 if(!ps_pkt && proto_type != PS_PROTO_OPEN_PORT)
00368 return -1;
00369
00370 if(ps_pkt)
00371 {
00372 p = (Packet *)ps_pkt->pkt;
00373
00374 if(!p->iph)
00375 return -1;
00376
00377 hlen = IP_HLEN(p->iph)<<2;
00378
00379 if ( p->iph != g_tmp_pkt->iph )
00380
00381
00382
00383
00384 memcpy(g_tmp_pkt->iph, p->iph, hlen);
00385
00386 if(ps_pkt->reverse_pkt)
00387 {
00388 tmp_addr = p->iph->ip_src.s_addr;
00389 g_tmp_pkt->iph->ip_src.s_addr = p->iph->ip_dst.s_addr;
00390 g_tmp_pkt->iph->ip_dst.s_addr = tmp_addr;
00391 }
00392
00393 ip_size += hlen;
00394
00395 g_tmp_pkt->iph->ip_proto = 0xff;
00396 g_tmp_pkt->iph->ip_ttl = 0x00;
00397 g_tmp_pkt->data = (u_char *)((u_char *)g_tmp_pkt->iph + hlen);
00398
00399 g_tmp_pkt->pkth->ts.tv_sec = p->pkth->ts.tv_sec;
00400 g_tmp_pkt->pkth->ts.tv_usec = p->pkth->ts.tv_usec;
00401 }
00402
00403 switch(proto_type)
00404 {
00405 case PS_PROTO_TCP:
00406 case PS_PROTO_UDP:
00407 case PS_PROTO_ICMP:
00408 case PS_PROTO_IP:
00409 if(MakeProtoInfo(proto, g_tmp_pkt->data, &ip_size))
00410 return -1;
00411
00412 break;
00413
00414 case PS_PROTO_OPEN_PORT:
00415 if(MakeOpenPortInfo(proto, g_tmp_pkt->data, &ip_size, user))
00416 return -1;
00417
00418 break;
00419
00420 default:
00421 return -1;
00422 }
00423
00424
00425
00426
00427 g_tmp_pkt->iph->ip_len = htons((short)ip_size);
00428 g_tmp_pkt->iph->ip_csum = 0;
00429 g_tmp_pkt->iph->ip_csum =
00430 in_chksum_ip((u_short *)g_tmp_pkt->iph, (IP_HLEN(g_tmp_pkt->iph)<<2));
00431
00432
00433
00434
00435
00436 g_tmp_pkt->pkth->caplen = ip_size + ETHERNET_HEADER_LEN;
00437 g_tmp_pkt->pkth->len = ip_size + ETHERNET_HEADER_LEN;
00438
00439 return 0;
00440 }
00441
00442 static int PortscanAlertTcp(Packet *p, PS_PROTO *proto, int proto_type)
00443 {
00444 int iCtr;
00445 unsigned int event_ref;
00446 int portsweep = 0;
00447
00448 if(!proto)
00449 return -1;
00450
00451 switch(proto->alerts)
00452 {
00453 case PS_ALERT_ONE_TO_ONE:
00454 event_ref = GeneratePSSnortEvent(p, GENERATOR_PSNG,
00455 PSNG_TCP_PORTSCAN, 0, 0, 3, PSNG_TCP_PORTSCAN_STR);
00456 break;
00457
00458 case PS_ALERT_ONE_TO_ONE_DECOY:
00459 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00460 PSNG_TCP_DECOY_PORTSCAN,0,0,3,PSNG_TCP_DECOY_PORTSCAN_STR);
00461 break;
00462
00463 case PS_ALERT_PORTSWEEP:
00464 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00465 PSNG_TCP_PORTSWEEP, 0, 0, 3, PSNG_TCP_PORTSWEEP_STR);
00466 portsweep = 1;
00467
00468 break;
00469
00470 case PS_ALERT_DISTRIBUTED:
00471 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00472 PSNG_TCP_DISTRIBUTED_PORTSCAN, 0, 0, 3,
00473 PSNG_TCP_DISTRIBUTED_PORTSCAN_STR);
00474 break;
00475
00476 case PS_ALERT_ONE_TO_ONE_FILTERED:
00477 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00478 PSNG_TCP_FILTERED_PORTSCAN,0,0,3,
00479 PSNG_TCP_FILTERED_PORTSCAN_STR);
00480 break;
00481
00482 case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
00483 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00484 PSNG_TCP_FILTERED_DECOY_PORTSCAN, 0,0,3,
00485 PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR);
00486 break;
00487
00488 case PS_ALERT_PORTSWEEP_FILTERED:
00489 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00490 PSNG_TCP_PORTSWEEP_FILTERED,0,0,3,
00491 PSNG_TCP_PORTSWEEP_FILTERED_STR);
00492 portsweep = 1;
00493
00494 return 0;
00495
00496 case PS_ALERT_DISTRIBUTED_FILTERED:
00497 event_ref = GeneratePSSnortEvent(p,GENERATOR_PSNG,
00498 PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN, 0, 0, 3,
00499 PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR);
00500 break;
00501
00502 default:
00503 return 0;
00504 }
00505
00506
00507
00508
00509 proto->event_ref = event_ref;
00510 proto->event_time.tv_sec = p->pkth->ts.tv_sec;
00511 proto->event_time.tv_usec = p->pkth->ts.tv_usec;
00512
00513
00514
00515
00516
00517 if(proto->open_ports_cnt && !portsweep)
00518 {
00519 for(iCtr = 0; iCtr < proto->open_ports_cnt; iCtr++)
00520 {
00521 PS_PKT ps_pkt;
00522
00523 memset(&ps_pkt, 0x00, sizeof(PS_PKT));
00524 ps_pkt.pkt = (void *)p;
00525
00526 if(MakePortscanPkt(&ps_pkt, proto, PS_PROTO_OPEN_PORT,
00527 (void *)&proto->open_ports[iCtr]))
00528 return -1;
00529
00530 g_tmp_pkt->pkth->ts.tv_usec += 1;
00531 GenerateOpenPortEvent(g_tmp_pkt,GENERATOR_PSNG,PSNG_OPEN_PORT,
00532 0,0,3, proto->event_ref, &proto->event_time,
00533 PSNG_OPEN_PORT_STR);
00534 }
00535 }
00536
00537 return 0;
00538 }
00539
00540 static int PortscanAlertUdp(Packet *p, PS_PROTO *proto, int proto_type)
00541 {
00542 if(!proto)
00543 return -1;
00544
00545 switch(proto->alerts)
00546 {
00547 case PS_ALERT_ONE_TO_ONE:
00548 GeneratePSSnortEvent(p, GENERATOR_PSNG, PSNG_UDP_PORTSCAN, 0, 0, 3,
00549 PSNG_UDP_PORTSCAN_STR);
00550 break;
00551
00552 case PS_ALERT_ONE_TO_ONE_DECOY:
00553 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_UDP_DECOY_PORTSCAN, 0, 0, 3,
00554 PSNG_UDP_DECOY_PORTSCAN_STR);
00555 break;
00556
00557 case PS_ALERT_PORTSWEEP:
00558 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_UDP_PORTSWEEP, 0, 0, 3,
00559 PSNG_UDP_PORTSWEEP_STR);
00560 break;
00561
00562 case PS_ALERT_DISTRIBUTED:
00563 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_UDP_DISTRIBUTED_PORTSCAN,
00564 0, 0, 3, PSNG_UDP_DISTRIBUTED_PORTSCAN_STR);
00565 break;
00566
00567 case PS_ALERT_ONE_TO_ONE_FILTERED:
00568 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_UDP_FILTERED_PORTSCAN,0,0,3,
00569 PSNG_UDP_FILTERED_PORTSCAN_STR);
00570 break;
00571
00572 case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
00573 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_UDP_FILTERED_DECOY_PORTSCAN,
00574 0,0,3, PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR);
00575 break;
00576
00577 case PS_ALERT_PORTSWEEP_FILTERED:
00578 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_UDP_PORTSWEEP_FILTERED,0,0,3,
00579 PSNG_UDP_PORTSWEEP_FILTERED_STR);
00580 break;
00581
00582 case PS_ALERT_DISTRIBUTED_FILTERED:
00583 GeneratePSSnortEvent(p,GENERATOR_PSNG,
00584 PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN, 0, 0, 3,
00585 PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR);
00586 break;
00587
00588 default:
00589 break;
00590 }
00591
00592 return 0;
00593 }
00594
00595 static int PortscanAlertIp(Packet *p, PS_PROTO *proto, int proto_type)
00596 {
00597 if(!proto)
00598 return -1;
00599
00600 switch(proto->alerts)
00601 {
00602 case PS_ALERT_ONE_TO_ONE:
00603 GeneratePSSnortEvent(p, GENERATOR_PSNG, PSNG_IP_PORTSCAN, 0, 0, 3,
00604 PSNG_IP_PORTSCAN_STR);
00605 break;
00606
00607 case PS_ALERT_ONE_TO_ONE_DECOY:
00608 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_IP_DECOY_PORTSCAN, 0, 0, 3,
00609 PSNG_IP_DECOY_PORTSCAN_STR);
00610 break;
00611
00612 case PS_ALERT_PORTSWEEP:
00613 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_IP_PORTSWEEP, 0, 0, 3,
00614 PSNG_IP_PORTSWEEP_STR);
00615 break;
00616
00617 case PS_ALERT_DISTRIBUTED:
00618 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_IP_DISTRIBUTED_PORTSCAN,
00619 0, 0, 3, PSNG_IP_DISTRIBUTED_PORTSCAN_STR);
00620 break;
00621
00622 case PS_ALERT_ONE_TO_ONE_FILTERED:
00623 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_IP_FILTERED_PORTSCAN,0,0,3,
00624 PSNG_IP_FILTERED_PORTSCAN_STR);
00625 break;
00626
00627 case PS_ALERT_ONE_TO_ONE_DECOY_FILTERED:
00628 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_IP_FILTERED_DECOY_PORTSCAN,
00629 0,0,3, PSNG_IP_FILTERED_DECOY_PORTSCAN_STR);
00630 break;
00631
00632 case PS_ALERT_PORTSWEEP_FILTERED:
00633 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_IP_PORTSWEEP_FILTERED,0,0,3,
00634 PSNG_IP_PORTSWEEP_FILTERED_STR);
00635 break;
00636
00637 case PS_ALERT_DISTRIBUTED_FILTERED:
00638 GeneratePSSnortEvent(p,GENERATOR_PSNG,
00639 PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN, 0, 0, 3,
00640 PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR);
00641 break;
00642
00643 default:
00644 break;
00645 }
00646
00647 return 0;
00648 }
00649
00650 static int PortscanAlertIcmp(Packet *p, PS_PROTO *proto, int proto_type)
00651 {
00652 if(!proto)
00653 return -1;
00654
00655 switch(proto->alerts)
00656 {
00657 case PS_ALERT_PORTSWEEP:
00658 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_ICMP_PORTSWEEP, 0, 0, 3,
00659 PSNG_ICMP_PORTSWEEP_STR);
00660 break;
00661
00662 case PS_ALERT_PORTSWEEP_FILTERED:
00663 GeneratePSSnortEvent(p,GENERATOR_PSNG,PSNG_ICMP_PORTSWEEP_FILTERED,0,0,3,
00664 PSNG_ICMP_PORTSWEEP_FILTERED_STR);
00665 break;
00666
00667 default:
00668 break;
00669 }
00670
00671 return 0;
00672 }
00673
00674 static int PortscanAlert(PS_PKT *ps_pkt, PS_PROTO *proto, int proto_type)
00675 {
00676 Packet *p;
00677
00678 if(!ps_pkt || !ps_pkt->pkt)
00679 return -1;
00680
00681 p = (Packet *)ps_pkt->pkt;
00682
00683 if(proto->alerts == PS_ALERT_OPEN_PORT)
00684 {
00685 if(MakePortscanPkt(ps_pkt, proto, PS_PROTO_OPEN_PORT, (void *)&p->sp))
00686 return -1;
00687
00688 GenerateOpenPortEvent(g_tmp_pkt,GENERATOR_PSNG,PSNG_OPEN_PORT,0,0,3,
00689 proto->event_ref, &proto->event_time, PSNG_OPEN_PORT_STR);
00690 }
00691 else
00692 {
00693 if(MakePortscanPkt(ps_pkt, proto, proto_type, NULL))
00694 return -1;
00695
00696 switch(proto_type)
00697 {
00698 case PS_PROTO_TCP:
00699 PortscanAlertTcp(g_tmp_pkt, proto, proto_type);
00700
00701 #ifdef GIDS
00702 if((SppStickydIsRunning()) && sdt.sfportscan)
00703 {
00704 AddIpToBlockTree(g_tmp_pkt, 0, sdt.sfportscan);
00705 }
00706 #endif
00707
00708 break;
00709
00710 case PS_PROTO_UDP:
00711 PortscanAlertUdp(g_tmp_pkt, proto, proto_type);
00712
00713 #ifdef GIDS
00714 if((SppStickydIsRunning()) && sdt.sfportscan)
00715 {
00716 AddIpToBlockTree(g_tmp_pkt, 0, sdt.sfportscan);
00717 }
00718 #endif
00719
00720 break;
00721
00722 case PS_PROTO_ICMP:
00723 PortscanAlertIcmp(g_tmp_pkt, proto, proto_type);
00724
00725 #ifdef GIDS
00726 if((SppStickydIsRunning()) && sdt.sfportscan)
00727 {
00728 AddIpToBlockTree(g_tmp_pkt, 0, sdt.sfportscan);
00729 }
00730 #endif
00731
00732 break;
00733
00734 case PS_PROTO_IP:
00735 PortscanAlertIp(g_tmp_pkt, proto, proto_type);
00736
00737 #ifdef GIDS
00738 if((SppStickydIsRunning()) && sdt.sfportscan)
00739 {
00740 AddIpToBlockTree(g_tmp_pkt, 0, sdt.sfportscan);
00741 }
00742 #endif
00743
00744 break;
00745 }
00746 }
00747
00748 return 0;
00749 }
00750
00751 static void PortscanDetect(Packet *p, void *context)
00752 {
00753 PS_PKT ps_pkt;
00754
00755 if(!p || !p->iph || (p->packet_flags & PKT_REBUILT_STREAM))
00756 return;
00757
00758 if(!(p->preprocessors & PP_SFPORTSCAN))
00759 {
00760 return;
00761 }
00762
00763 memset(&ps_pkt, 0x00, sizeof(PS_PKT));
00764 ps_pkt.pkt = (void *)p;
00765
00766 ps_detect(&ps_pkt);
00767
00768 if(ps_pkt.scanner && ps_pkt.scanner->proto[ps_pkt.proto_idx].alerts &&
00769 (ps_pkt.scanner->proto[ps_pkt.proto_idx].alerts != PS_ALERT_GENERATED))
00770 {
00771 PortscanAlert(&ps_pkt, &ps_pkt.scanner->proto[ps_pkt.proto_idx],
00772 ps_pkt.proto);
00773 }
00774
00775 if(ps_pkt.scanned && ps_pkt.scanned->proto[ps_pkt.proto_idx].alerts &&
00776 (ps_pkt.scanned->proto[ps_pkt.proto_idx].alerts != PS_ALERT_GENERATED))
00777 {
00778 PortscanAlert(&ps_pkt, &ps_pkt.scanned->proto[ps_pkt.proto_idx],
00779 ps_pkt.proto);
00780 }
00781
00782 return;
00783 }
00784
00785 static void FatalErrorNoOption(u_char *option)
00786 {
00787 FatalError("%s(%d) => No argument to '%s' config option.\n",
00788 file_name, file_line, option);
00789
00790 return;
00791 }
00792
00793 static void FatalErrorNoEnd(char *option)
00794 {
00795 FatalError("%s(%d) => No ending brace to '%s' config option.\n",
00796 file_name, file_line, option);
00797 }
00798
00799 static void FatalErrorInvalidArg(char *option)
00800 {
00801 FatalError("%s(%d) => Invalid argument to '%s' config option.\n",
00802 file_name, file_line, option);
00803 }
00804
00805 static void FatalErrorInvalidOption(char *option)
00806 {
00807 FatalError("%s(%d) => Invalid option '%s' to portscan preprocessor.\n",
00808 file_name, file_line, option);
00809 }
00810
00811 static void ParseProtos(int *protos)
00812 {
00813 char *pcTok;
00814
00815 if(!protos)
00816 return;
00817
00818 *protos = 0;
00819
00820 pcTok = strtok(NULL, DELIMITERS);
00821 while(pcTok)
00822 {
00823 if(!strcasecmp(pcTok, "tcp"))
00824 *protos |= PS_PROTO_TCP;
00825 else if(!strcasecmp(pcTok, "udp"))
00826 *protos |= PS_PROTO_UDP;
00827 else if(!strcasecmp(pcTok, "icmp"))
00828 *protos |= PS_PROTO_ICMP;
00829 else if(!strcasecmp(pcTok, "ip"))
00830 *protos |= PS_PROTO_IP;
00831 else if(!strcasecmp(pcTok, "all"))
00832 *protos = PS_PROTO_ALL;
00833 else if(!strcasecmp(pcTok, TOKEN_ARG_END))
00834 return;
00835 else
00836 FatalErrorInvalidArg("proto");
00837
00838 pcTok = strtok(NULL, DELIMITERS);
00839 }
00840
00841 if(!pcTok)
00842 FatalErrorNoEnd("proto");
00843
00844 return;
00845 }
00846
00847 static void ParseScanType(int *scan_types)
00848 {
00849 char *pcTok;
00850
00851 if(!scan_types)
00852 return;
00853
00854 *scan_types = 0;
00855
00856 pcTok = strtok(NULL, DELIMITERS);
00857 while(pcTok)
00858 {
00859 if(!strcasecmp(pcTok, "portscan"))
00860 *scan_types |= PS_TYPE_PORTSCAN;
00861 else if(!strcasecmp(pcTok, "portsweep"))
00862 *scan_types |= PS_TYPE_PORTSWEEP;
00863 else if(!strcasecmp(pcTok, "decoy_portscan"))
00864 *scan_types |= PS_TYPE_DECOYSCAN;
00865 else if(!strcasecmp(pcTok, "distributed_portscan"))
00866 *scan_types |= PS_TYPE_DISTPORTSCAN;
00867 else if(!strcasecmp(pcTok, "all"))
00868 *scan_types = PS_TYPE_ALL;
00869 else if(!strcasecmp(pcTok, TOKEN_ARG_END))
00870 return;
00871 else
00872 FatalErrorInvalidArg("scan_type");
00873
00874 pcTok = strtok(NULL, DELIMITERS);
00875 }
00876
00877 if(!pcTok)
00878 FatalErrorNoEnd("scan_type");
00879
00880 return;
00881 }
00882
00883 static void ParseSenseLevel(int *sense_level)
00884 {
00885 char *pcTok;
00886
00887 if(!sense_level)
00888 return;
00889
00890 *sense_level = 0;
00891
00892 pcTok = strtok(NULL, DELIMITERS);
00893 while(pcTok)
00894 {
00895 if(!strcasecmp(pcTok, "low"))
00896 *sense_level = PS_SENSE_LOW;
00897 else if(!strcasecmp(pcTok, "medium"))
00898 *sense_level = PS_SENSE_MEDIUM;
00899 else if(!strcasecmp(pcTok, "high"))
00900 *sense_level = PS_SENSE_HIGH;
00901 else if(!strcmp(pcTok, TOKEN_ARG_END))
00902 return;
00903 else
00904 FatalErrorInvalidArg("sense_level");
00905
00906 pcTok = strtok(NULL, DELIMITERS);
00907 }
00908
00909 if(!pcTok)
00910 FatalErrorNoEnd("sense_level");
00911
00912 return;
00913 }
00914
00915 static void ParseIpList(IPSET **ip_list, char *option)
00916 {
00917 char *pcTok;
00918
00919 if(!ip_list)
00920 return;
00921
00922 pcTok = strtok(NULL, TOKEN_ARG_END);
00923 if(!pcTok)
00924 FatalErrorInvalidArg(option);
00925
00926 *ip_list = ipset_new(IPV4_FAMILY);
00927 if(!*ip_list)
00928 FatalError("Failed to initialize ip_list in portscan preprocessor.\n");
00929
00930 if(ip4_setparse(*ip_list, pcTok))
00931 FatalError("%s(%d) => Invalid ip_list to '%s' option.\n",
00932 file_name, file_line, option);
00933
00934 return;
00935 }
00936
00937 static void ParseMemcap(int *memcap)
00938 {
00939 char *pcTok;
00940
00941 if(!memcap)
00942 return;
00943
00944 *memcap = 0;
00945
00946 pcTok = strtok(NULL, DELIMITERS);
00947 if(!pcTok)
00948 FatalErrorNoEnd("memcap");
00949
00950 *memcap = atoi(pcTok);
00951
00952 if(*memcap <= 0)
00953 FatalErrorInvalidArg("memcap");
00954
00955 pcTok = strtok(NULL, DELIMITERS);
00956 if(!pcTok)
00957 FatalErrorNoEnd("memcap");
00958
00959 if(strcmp(pcTok, TOKEN_ARG_END))
00960 FatalErrorInvalidArg("memcap");
00961
00962 return;
00963 }
00964
00965 static void PrintPortscanConf(int detect_scans, int detect_scan_type,
00966 int sense_level, IPSET *scanner, IPSET *scanned, IPSET *watch,
00967 int memcap)
00968 {
00969 char buf[STD_BUF+1];
00970 char ip_str[80], mask_str[80];
00971 int proto_cnt = 0;
00972 CIDRBLOCK *p;
00973
00974 LogMessage("Portscan Detection Config:\n");
00975
00976 memset(buf, 0, STD_BUF+1);
00977 snprintf(buf, STD_BUF, " Detect Protocols: ");
00978 if(detect_scans & PS_PROTO_TCP) { sfsnprintfappend(buf, STD_BUF, "TCP "); proto_cnt++; }
00979 if(detect_scans & PS_PROTO_UDP) { sfsnprintfappend(buf, STD_BUF, "UDP "); proto_cnt++; }
00980 if(detect_scans & PS_PROTO_ICMP) { sfsnprintfappend(buf, STD_BUF, "ICMP "); proto_cnt++; }
00981 if(detect_scans & PS_PROTO_IP) { sfsnprintfappend(buf, STD_BUF, "IP"); proto_cnt++; }
00982 LogMessage("%s\n", buf);
00983
00984 memset(buf, 0, STD_BUF+1);
00985 snprintf(buf, STD_BUF, " Detect Scan Type: ");
00986 if(detect_scan_type & PS_TYPE_PORTSCAN)
00987 sfsnprintfappend(buf, STD_BUF, "portscan ");
00988 if(detect_scan_type & PS_TYPE_PORTSWEEP)
00989 sfsnprintfappend(buf, STD_BUF, "portsweep ");
00990 if(detect_scan_type & PS_TYPE_DECOYSCAN)
00991 sfsnprintfappend(buf, STD_BUF, "decoy_portscan ");
00992 if(detect_scan_type & PS_TYPE_DISTPORTSCAN)
00993 sfsnprintfappend(buf, STD_BUF, "distributed_portscan");
00994 LogMessage("%s\n", buf);
00995
00996 memset(buf, 0, STD_BUF+1);
00997 snprintf(buf, STD_BUF, " Sensitivity Level: ");
00998 if(sense_level == PS_SENSE_HIGH)
00999 sfsnprintfappend(buf, STD_BUF, "High/Experimental");
01000 if(sense_level == PS_SENSE_MEDIUM)
01001 sfsnprintfappend(buf, STD_BUF, "Medium");
01002 if(sense_level == PS_SENSE_LOW)
01003 sfsnprintfappend(buf, STD_BUF, "Low");
01004 LogMessage("%s\n", buf);
01005
01006 LogMessage(" Memcap (in bytes): %d\n", memcap);
01007 LogMessage(" Number of Nodes: %d\n",
01008 memcap / (sizeof(PS_PROTO)*proto_cnt-1));
01009
01010 if(g_logpath[0])
01011 LogMessage(" Logfile: %s\n", g_logpath);
01012
01013 if(scanner)
01014 {
01015 LogMessage(" Ignore Scanner IP List:\n");
01016 for(p = (CIDRBLOCK*)sflist_first(&scanner->cidr_list);
01017 p;
01018 p = (CIDRBLOCK*)sflist_next(&scanner->cidr_list))
01019 {
01020 ip4_sprintx(ip_str, sizeof(ip_str), &p->ip);
01021 ip4_sprintx(mask_str, sizeof(mask_str), &p->mask);
01022
01023 if(p->notflag)
01024 LogMessage(" !%s / %s\n", ip_str, mask_str);
01025 else
01026 LogMessage(" %s / %s\n", ip_str, mask_str);
01027 }
01028 }
01029
01030 if(scanned)
01031 {
01032 LogMessage(" Ignore Scanned IP List:\n");
01033 for(p = (CIDRBLOCK*)sflist_first(&scanned->cidr_list);
01034 p;
01035 p = (CIDRBLOCK*)sflist_next(&scanned->cidr_list))
01036 {
01037 ip4_sprintx(ip_str, sizeof(ip_str), &p->ip);
01038 ip4_sprintx(mask_str, sizeof(mask_str), &p->mask);
01039
01040 if(p->notflag)
01041 LogMessage(" !%s / %s\n", ip_str, mask_str);
01042 else
01043 LogMessage(" %s / %s\n", ip_str, mask_str);
01044 }
01045 }
01046
01047 if(watch)
01048 {
01049 LogMessage(" Ignore Watch IP List:\n");
01050 for(p = (CIDRBLOCK*)sflist_first(&watch->cidr_list);
01051 p;
01052 p = (CIDRBLOCK*)sflist_next(&watch->cidr_list))
01053 {
01054 ip4_sprintx(ip_str, sizeof(ip_str), &p->ip);
01055 ip4_sprintx(mask_str, sizeof(mask_str), &p->mask);
01056
01057 if(p->notflag)
01058 LogMessage(" !%s / %s\n", ip_str, mask_str);
01059 else
01060 LogMessage(" %s / %s\n", ip_str, mask_str);
01061 }
01062 }
01063
01064 LogMessage("\n");
01065
01066 return;
01067 }
01068
01069 static void ParseLogFile(FILE **flog, u_char *logfile, int logfile_size)
01070 {
01071 char *pcTok;
01072
01073 pcTok = strtok(NULL, DELIMITERS);
01074 if(!pcTok)
01075 FatalErrorNoEnd("logfile");
01076
01077 if(pcTok[0] == '/')
01078 snprintf(logfile, logfile_size, "%s", pcTok);
01079 else
01080 snprintf(logfile, logfile_size, "%s/%s", pv.log_dir,pcTok);
01081
01082 pcTok = strtok(NULL, DELIMITERS);
01083 if(!pcTok)
01084 FatalErrorNoEnd("logfile");
01085
01086 if(strcmp(pcTok, TOKEN_ARG_END))
01087 FatalErrorInvalidArg("logfile");
01088
01089 *flog = fopen(logfile, "a+");
01090 if(!(*flog))
01091 FatalError("%s(%d) => '%s' could not be opened.\n",
01092 file_name, file_line, logfile);
01093
01094 return;
01095 }
01096
01097 static void PortscanInit(u_char *args)
01098 {
01099 int sense_level = PS_SENSE_LOW;
01100 int protos = (PS_PROTO_TCP | PS_PROTO_UDP);
01101 int scan_types = PS_TYPE_ALL;
01102 int memcap = 1048576;
01103 IPSET *ignore_scanners = NULL;
01104 IPSET *ignore_scanned = NULL;
01105 IPSET *watch_ip = NULL;
01106 char *pcTok;
01107 int iRet;
01108
01109 g_logpath[0] = 0x00;
01110
01111 if(args)
01112 {
01113 pcTok = strtok(args, DELIMITERS);
01114 while(pcTok)
01115 {
01116 if(!strcasecmp(pcTok, "proto"))
01117 {
01118 pcTok = strtok(NULL, DELIMITERS);
01119 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01120 FatalErrorNoOption("proto");
01121
01122 ParseProtos(&protos);
01123 }
01124 else if(!strcasecmp(pcTok, "scan_type"))
01125 {
01126 pcTok = strtok(NULL, DELIMITERS);
01127 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01128 FatalErrorNoOption("scan_type");
01129
01130 ParseScanType(&scan_types);
01131 }
01132 else if(!strcasecmp(pcTok, "sense_level"))
01133 {
01134 pcTok = strtok(NULL, DELIMITERS);
01135 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01136 FatalErrorNoOption("sense_level");
01137
01138 ParseSenseLevel(&sense_level);
01139 }
01140 else if(!strcasecmp(pcTok, "ignore_scanners"))
01141 {
01142 pcTok = strtok(NULL, DELIMITERS);
01143 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01144 FatalErrorNoOption("ignore_scanners");
01145
01146 ParseIpList(&ignore_scanners, "ignore_scanners");
01147 }
01148 else if(!strcasecmp(pcTok, "ignore_scanned"))
01149 {
01150 pcTok = strtok(NULL, DELIMITERS);
01151 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01152 FatalErrorNoOption("ignore_scanned");
01153
01154 ParseIpList(&ignore_scanned, "ignore_scanned");
01155 }
01156 else if(!strcasecmp(pcTok, "watch_ip"))
01157 {
01158 pcTok = strtok(NULL, DELIMITERS);
01159 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01160 FatalErrorNoOption("watch_ip");
01161
01162 ParseIpList(&watch_ip, "watch_ip");
01163 }
01164 else if(!strcasecmp(pcTok, "print_tracker"))
01165 {
01166 g_print_tracker = 1;
01167 }
01168 else if(!strcasecmp(pcTok, "memcap"))
01169 {
01170 pcTok = strtok(NULL, DELIMITERS);
01171 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01172 FatalErrorNoOption("memcap");
01173
01174 ParseMemcap(&memcap);
01175 }
01176 else if(!strcasecmp(pcTok, "logfile"))
01177 {
01178 pcTok = strtok(NULL, DELIMITERS);
01179 if(!pcTok || strcmp(pcTok, TOKEN_ARG_BEGIN))
01180 FatalErrorNoOption("logfile");
01181
01182 ParseLogFile(&g_logfile, g_logpath, sizeof(g_logpath));
01183 }
01184 else if(!strcasecmp(pcTok, "include_midstream"))
01185 {
01186 g_include_midstream = 1;
01187 }
01188 else
01189 {
01190 FatalErrorInvalidOption(pcTok);
01191 }
01192
01193 pcTok = strtok(NULL, DELIMITERS);
01194 }
01195 }
01196
01197 if((iRet = ps_init(protos, scan_types, sense_level, ignore_scanners,
01198 ignore_scanned, watch_ip, memcap)))
01199 {
01200 if(iRet == -2)
01201 {
01202 FatalError("%s(%d) => 'memcap' limit not sufficient to run "
01203 "sfportscan preprocessor. Please increase this "
01204 "value or keep the default memory usage.\n",
01205 file_name, file_line);
01206 }
01207
01208 FatalError("Failed to initialize the sfportscan detection module. "
01209 "Please check your configuration before submitting a "
01210 "bug.\n");
01211 }
01212
01213 AddFuncToPreprocList(PortscanDetect);
01214
01215 PrintPortscanConf(protos, scan_types, sense_level, ignore_scanners,
01216 ignore_scanned, watch_ip, memcap);
01217
01218 PortscanPacketInit();
01219
01220 return;
01221 }
01222
01223 void SetupPsng(void)
01224 {
01225 RegisterPreprocessor("sfportscan", PortscanInit);
01226
01227 return;
01228 }