00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "debug.h"
00015 #include "plugbase.h"
00016 #include "parser.h"
00017 #include "snort.h"
00018
00019 #include "scoreboard.h"
00020 #include "server_stats.h"
00021
00022 #include "spp_flow.h"
00023 #include "flowps.h"
00024 #include "flowps_snort.h"
00025
00026 #include "packet_time.h"
00027 #include "event_wrapper.h"
00028 #include "generators.h"
00029 #include "common_defs.h"
00030 #include "util_str.h"
00031 #include "util_net.h"
00032
00033 #ifndef WIN32
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <arpa/inet.h>
00037 #endif
00038
00039 #include <stdlib.h>
00040 #include <ctype.h>
00041
00042 #define PSDEFAULT_SB_ROWS_ACTIVE 1000000
00043 #define PSDEFAULT_SB_MEMCAP_ACTIVE (ONE_MBYTE * 24)
00044 #define PSDEFAULT_SB_ROWS_SCANNER (PSDEFAULT_SB_ROWS_ACTIVE/4)
00045 #define PSDEFAULT_SB_MEMCAP_SCANNER (PSDEFAULT_SB_MEMCAP_ACTIVE/4)
00046 #define PSDEFAULT_UT_ROWS 1000000
00047 #define PSDEFAULT_UT_MEMCAP (ONE_MBYTE * 24)
00048 #define PSDEFAULT_SERVER_ROWS (1 << 16)
00049 #define PSDEFAULT_SERVER_MEMCAP (ONE_MBYTE * 2)
00050 #define PSDEFAULT_SERVER_LEARNING_TIME (ONE_HOUR * 8)
00051 #define PSDEFAULT_SERVER_IGNORE_LIMIT 500
00052 #define PSDEFAULT_SERVER_SCANNER_LIMIT 500
00053 #define PSDEFAULT_BASE_SCORE 1
00054 #define PSDEFAULT_ALERT_ONCE 1
00055 #define PSDEFAULT_OUTPUT_MODE VARIABLEMSG
00056
00057
00058
00059 #define PSDEFAULT_TCP_PENALTIES 1
00060
00061
00062 #define PSTALKER_FIXED_SIZE 30
00063 #define PSTALKER_SLIDING_SIZE 30
00064 #define PSTALKER_SLIDING_SCORE 30
00065 #define PSTALKER_FIXED_SCORE 15
00066 #define PSTALKER_WINDOW_SCALE (0.5)
00067
00068 #define PSSCANNER_FIXED_SIZE 15
00069 #define PSSCANNER_SLIDING_SIZE 20
00070 #define PSSCANNER_SLIDING_SCORE 40
00071 #define PSSCANNER_FIXED_SCORE 15
00072 #define PSSCANNER_WINDOW_SCALE (0.5)
00073
00074 #define FLOWPSMAXPKTSIZE (IP_MAXPACKET - (IP_HEADER_LEN + ETHERNET_HEADER_LEN))
00075
00076 static PS_TRACKER s_tracker;
00077 static int s_debug = 0;
00078 static Packet *s_pkt = NULL;
00079
00080 void FlowPSRestart(int signal, void *data);
00081 void FlowPSCleanExit(int signal, void *data);
00082 static void FlowPSInit(u_char *args);
00083 static void FlowPSParseArgs(PS_CONFIG *config , char *args);
00084 static int flowps_generate_flow_event(SCORE_ENTRY *sep, FLOWPACKET *p, u_int32_t *address, FLOWPS_OUTPUT output_type, time_t cur);
00085 static int flowps_init_pkt(void);
00086
00087 static Packet *flowps_mkpacket(SCORE_ENTRY *sep, FLOWPACKET *orig_packet, u_int32_t *address, time_t cur);
00088
00089
00090 void FlowPSSetDefaults(PS_CONFIG *config)
00091 {
00092 flowps_mkconfig(config,
00093 PSDEFAULT_SB_MEMCAP_ACTIVE,
00094 PSDEFAULT_SB_ROWS_ACTIVE,
00095 PSDEFAULT_SB_MEMCAP_SCANNER,
00096 PSDEFAULT_SB_ROWS_SCANNER,
00097 PSDEFAULT_UT_MEMCAP,
00098 PSDEFAULT_UT_ROWS,
00099 PSDEFAULT_SERVER_MEMCAP,
00100 PSDEFAULT_SERVER_ROWS,
00101 PSDEFAULT_SERVER_LEARNING_TIME,
00102 PSDEFAULT_TCP_PENALTIES,
00103 PSDEFAULT_SERVER_IGNORE_LIMIT,
00104 PSDEFAULT_SERVER_SCANNER_LIMIT,
00105 PSDEFAULT_BASE_SCORE,
00106 PSDEFAULT_ALERT_ONCE,
00107 PSDEFAULT_OUTPUT_MODE);
00108
00109
00110 flowps_mkthreshold(&config->limit_talker,
00111 PSTALKER_FIXED_SIZE,
00112 PSTALKER_FIXED_SCORE,
00113 PSTALKER_SLIDING_SIZE,
00114 PSTALKER_SLIDING_SCORE,
00115 PSTALKER_WINDOW_SCALE);
00116
00117 flowps_mkthreshold(&config->limit_scanner,
00118 PSSCANNER_FIXED_SIZE,
00119 PSSCANNER_FIXED_SCORE,
00120 PSSCANNER_SLIDING_SIZE,
00121 PSSCANNER_SLIDING_SCORE,
00122 PSSCANNER_WINDOW_SCALE);
00123 }
00124
00125 void SetupFlowPS(void)
00126 {
00127 RegisterPreprocessor("flow-portscan", FlowPSInit);
00128 }
00129
00130
00131
00132
00133
00134
00135 static void FlowPSOutputConfig(PS_TRACKER *trackerp)
00136 {
00137 if(pv.quiet_flag)
00138 return;
00139
00140 flow_printf(",-----------[flow-portscan config]-------------\n");
00141 flow_printf("| TCP Penalties: %s\n", trackerp->config.tcp_penalties ? "On": "Off");
00142 flow_printf("| Ouput Mode: %s\n",
00143 (trackerp->config.output_mode == VARIABLEMSG) ? "msg" : "pktkludge");
00144 flow_printf("| Base Score: %d\n", trackerp->config.base_score);
00145
00146 flow_printf("+----------------------------------------------\n");
00147 flow_printf("| Scoreboard: ACTIVE PORTSCANNER\n");
00148 flow_printf("| memcap: %-8d %-8d\n",
00149 scoreboard_memcap(&trackerp->table_active),
00150 scoreboard_memcap(&trackerp->table_scanner));
00151 flow_printf("| rows: %-8d %-8d\n",
00152 scoreboard_row_count(&trackerp->table_active),
00153 scoreboard_row_count(&trackerp->table_scanner));
00154 flow_printf("| overhead: %-8d(%%%.02lf) %-8d(%%%.02lf)\n",
00155 scoreboard_overhead_bytes(&trackerp->table_active),
00156 calc_percent(scoreboard_overhead_bytes(&trackerp->table_active),
00157 scoreboard_memcap(&trackerp->table_active)),
00158 scoreboard_overhead_bytes(&trackerp->table_scanner),
00159 calc_percent(scoreboard_overhead_bytes(&trackerp->table_scanner),
00160 scoreboard_memcap(&trackerp->table_scanner)));
00161
00162 flow_printf("| fixed-size: %-4ds %-4ds\n",
00163 trackerp->config.limit_talker.fixed_size,
00164 trackerp->config.limit_scanner.fixed_size);
00165 flow_printf("| sliding-size: %-4ds %-4ds\n",
00166 trackerp->config.limit_talker.sliding_size,
00167 trackerp->config.limit_scanner.sliding_size);
00168 flow_printf("| threshold-fixed: %-4u %-4u\n",
00169 trackerp->config.limit_talker.fixed,
00170 trackerp->config.limit_scanner.fixed);
00171 flow_printf("| threshold-sliding: %-4u %-4u\n",
00172 trackerp->config.limit_talker.sliding,
00173 trackerp->config.limit_scanner.sliding);
00174 flow_printf("| window scale: %-.2lf %-.2lf\n",
00175 trackerp->config.limit_talker.window_scale,
00176 trackerp->config.limit_scanner.window_scale);
00177
00178
00179 flow_printf("+----------------------------------------------\n");
00180 flow_printf("| Uniqueness: memcap: %8d rows: %8d\n",
00181 ut_memcap(&trackerp->unique_tracker),
00182 ut_row_count(&trackerp->unique_tracker));
00183 flow_printf("| overhead: %d (%%%.02lf)\n",
00184 ut_overhead_bytes(&trackerp->unique_tracker),
00185 calc_percent(ut_overhead_bytes(&trackerp->unique_tracker),
00186 ut_memcap(&trackerp->unique_tracker)));
00187
00188 if(flowps_server_stats_enabled(trackerp) == FLOW_SUCCESS)
00189 {
00190 flow_printf("+----------------------------------------------\n");
00191 flow_printf("| Server Stats: memcap: %8d rows: %8d\n",
00192 server_stats_memcap(&trackerp->server_stats),
00193 server_stats_row_count(&trackerp->server_stats));
00194 flow_printf("| overhead: %d (%%%.02lf)\n",
00195 server_stats_overhead_bytes(&trackerp->server_stats),
00196 calc_percent(server_stats_overhead_bytes(&trackerp->server_stats),
00197 server_stats_memcap(&trackerp->server_stats)));
00198 flow_printf("| learning time: %d\n",
00199 trackerp->config.server_learning_time);
00200 flow_printf("| ignore limit: %u\n",
00201 trackerp->config.server_ignore_limit);
00202 flow_printf("| scanner limit: %u\n",
00203 trackerp->config.server_scanner_limit);
00204
00205
00206 }
00207 else
00208 {
00209 flow_printf("| Server Stats: Disabled\n");
00210 }
00211
00212 flow_printf("`----------------------------------------------\n");
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222 static void FlowPSInit(u_char *args)
00223 {
00224 static int init_once = 0;
00225 int ret;
00226
00227 PS_TRACKER *pstp = &s_tracker;
00228 PS_CONFIG tconfig;
00229
00230 if(flowps_init_pkt())
00231 {
00232 flow_fatalerror("Error initializing flowps packet!\n");
00233 }
00234
00235 if(!SppFlowIsRunning())
00236 {
00237 flow_fatalerror("%s(%d) flow-portscan requires spp_flow to be enabled!\n",
00238 file_name, file_line);
00239 }
00240
00241 if(init_once)
00242 {
00243 flow_fatalerror("%s(%d) Unable to reinitialize flow-portscan!\n",
00244 file_name, file_line);
00245 }
00246 else
00247 {
00248 init_once = 1;
00249 }
00250
00251 FlowPSSetDefaults(&tconfig);
00252
00253 FlowPSParseArgs(&tconfig, args);
00254
00255
00256 if((ret = flowps_init(pstp, &tconfig)) != FLOW_SUCCESS)
00257 {
00258 flow_fatalerror("Unable to initialize the flow cache!"
00259 "-- try more memory (current memcap is %d)\n",
00260 tconfig.sb_memcap_total);
00261 }
00262
00263 FlowPSOutputConfig(pstp);
00264
00265 AddFuncToCleanExitList(FlowPSCleanExit, NULL);
00266 AddFuncToRestartList(FlowPSRestart, NULL);
00267 }
00268
00269
00270 static void FlowPSParseOption(PS_CONFIG *config,
00271 char *fname, int lineno,
00272 char *key, char *value)
00273 {
00274 int ivalue;
00275
00276 if(!key || !value)
00277 {
00278 flow_fatalerror("%s:(%d) Invalid command line arguments!\n");
00279 }
00280
00281 if(s_debug > 1)
00282 flow_printf("key: %s value: %s\n", key, value);
00283
00284 if(!strcasecmp(key, "scoreboard-memcap-talker"))
00285 {
00286 ivalue = atoi(value);
00287 config->sb_memcap_talker = ivalue;
00288 }
00289 else if(!strcasecmp(key, "scoreboard-memcap-scanner"))
00290 {
00291 ivalue = atoi(value);
00292 config->sb_memcap_scanner = ivalue;
00293 }
00294 else if(!strcasecmp(key,"unique-memcap"))
00295 {
00296 ivalue = atoi(value);
00297 config->ut_memcap = ivalue;
00298 }
00299 else if(!strcasecmp(key,"server-memcap"))
00300 {
00301 ivalue = atoi(value);
00302 config->server_memcap = ivalue;
00303 }
00304 else if(!strcasecmp(key, "scoreboard-rows-talker"))
00305 {
00306 ivalue = atoi(value);
00307 config->sb_rows_talker = ivalue;
00308 }
00309 else if(!strcasecmp(key, "scoreboard-rows-scanner"))
00310 {
00311 ivalue = atoi(value);
00312 config->sb_rows_scanner = ivalue;
00313 }
00314 else if(!strcasecmp(key,"unique-rows"))
00315 {
00316 ivalue = atoi(value);
00317 config->ut_rows = ivalue;
00318 }
00319 else if(!strcasecmp(key,"server-rows"))
00320 {
00321 ivalue = atoi(value);
00322 config->server_rows = ivalue;
00323 }
00324 else if(!strcasecmp(key, "server-watchnet"))
00325 {
00326 IPSET *ipset = ipset_new(IPV4_FAMILY);
00327
00328 if(!ipset || ip4_setparse(ipset, value) !=0)
00329 {
00330 flow_fatalerror("%s(%d) Unable to create an IPSet from %s\n",
00331 file_name,file_line,value);
00332 }
00333
00334 config->server_watchnet_ipv4 = ipset;
00335 }
00336 else if(!strcasecmp(key, "src-ignore-net"))
00337 {
00338 IPSET *ipset = ipset_new(IPV4_FAMILY);
00339
00340 if(!ipset || ip4_setparse(ipset, value) !=0)
00341 {
00342 flow_fatalerror("%s(%d) Unable to create an IPSet from %s\n",
00343 file_name,file_line,value);
00344 }
00345
00346 config->src_ignore_ipv4 = ipset;
00347 }
00348 else if(!strcasecmp(key, "dst-ignore-net"))
00349 {
00350 IPSET *ipset = ipset_new(IPV4_FAMILY);
00351
00352 if(!ipset || ip4_setparse(ipset, value) !=0)
00353 {
00354 flow_fatalerror("%s(%d) Unable to create an IPSet from %s\n",
00355 file_name,file_line,value);
00356 }
00357
00358 config->dst_ignore_ipv4 = ipset;
00359 }
00360 else if(!strcasecmp(key, "tcp-penalties"))
00361 {
00362 if(toggle_option(key, value, &config->tcp_penalties))
00363 {
00364 flow_fatalerror("%s(%d) Error processing %s directive (value = %s)\n",
00365 file_name,file_line,key,value);
00366 }
00367 }
00368 else if(!strcasecmp(key, "server-learning-time"))
00369 {
00370 ivalue = atoi(value);
00371 config->server_learning_time = ivalue;
00372 }
00373 else if(!strcasecmp(key, "server-ignore-limit"))
00374 {
00375 ivalue = atoi(value);
00376 config->server_ignore_limit = ivalue;
00377 }
00378 else if(!strcasecmp(key, "server-scanner-limit"))
00379 {
00380 ivalue = atoi(value);
00381 config->server_scanner_limit = ivalue;
00382 }
00383 else if(!strcasecmp(key, "talker-fixed-threshold"))
00384 {
00385 ivalue = atoi(value);
00386 config->limit_talker.fixed = ivalue;
00387 }
00388 else if(!strcasecmp(key, "talker-sliding-threshold"))
00389 {
00390 ivalue = atoi(value);
00391 config->limit_talker.sliding = ivalue;
00392 }
00393 else if(!strcasecmp(key, "talker-fixed-window"))
00394 {
00395 ivalue = atoi(value);
00396 config->limit_talker.fixed_size = ivalue;
00397 }
00398 else if(!strcasecmp(key, "talker-sliding-window"))
00399 {
00400 ivalue = atoi(value);
00401 config->limit_talker.sliding_size = ivalue;
00402 }
00403 else if(!strcasecmp(key, "talker-sliding-scale-factor"))
00404 {
00405 config->limit_talker.window_scale = strtod(value, NULL);
00406 }
00407 else if(!strcasecmp(key, "scanner-fixed-threshold"))
00408 {
00409 ivalue = atoi(value);
00410 config->limit_scanner.fixed = ivalue;
00411 }
00412 else if(!strcasecmp(key, "scanner-sliding-threshold"))
00413 {
00414 ivalue = atoi(value);
00415 config->limit_scanner.sliding = ivalue;
00416 }
00417 else if(!strcasecmp(key, "scanner-fixed-window"))
00418 {
00419 ivalue = atoi(value);
00420 config->limit_scanner.fixed_size = ivalue;
00421 }
00422 else if(!strcasecmp(key, "scanner-sliding-window"))
00423 {
00424 ivalue = atoi(value);
00425 config->limit_scanner.sliding_size = ivalue;
00426 }
00427 else if(!strcasecmp(key, "scanner-sliding-scale-factor"))
00428 {
00429 config->limit_scanner.window_scale = strtod(value, NULL);
00430 }
00431 else if(!strcasecmp(key, "base-score"))
00432 {
00433 config->base_score = atoi(value);
00434 }
00435 else if(!strcasecmp(key, "dumpall"))
00436 {
00437 config->dumpall = atoi(value);
00438 }
00439 else if(!strcasecmp(key, "alert-mode"))
00440 {
00441 if(!strcasecmp(value, "once"))
00442 {
00443 config->alert_once = 1;
00444 }
00445 else if(!strcasecmp(value, "all"))
00446 {
00447 config->alert_once = 0;
00448 }
00449 else
00450 {
00451 flow_fatalerror("%s(%d) Bad option to %s => %s\n",
00452 file_name, file_line, key, value);
00453 }
00454 }
00455 else if(!strcasecmp(key, "output-mode"))
00456 {
00457 if(!strcasecmp(value, "msg"))
00458 {
00459 config->output_mode = VARIABLEMSG;
00460 }
00461 else if(!strcasecmp(value, "pktkludge"))
00462 {
00463 config->output_mode = PKTKLUDGE;
00464 }
00465 else
00466 {
00467 flow_fatalerror("%s(%d) Bad option to %s => %s\n",
00468 file_name, file_line, key, value);
00469 }
00470 }
00471 else
00472 {
00473 flow_fatalerror("%s(%d) Unknown Arguments: key(%s) value(%s)\n",
00474 fname, lineno, key, value);
00475 }
00476
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 static void FlowPSParseArgs(PS_CONFIG *config , char *args)
00491 {
00492 const char *delim = " \t";
00493 char *key, *value;
00494 char *myargs;
00495
00496 if(!config)
00497 {
00498 flow_fatalerror("FlowPSParseArgs: NULL config passed\n!");
00499 }
00500
00501 if(!args)
00502 {
00503 return;
00504 }
00505
00506 while(isspace((int)*args))
00507 args++;
00508
00509 if(*args == '\0')
00510 {
00511 return;
00512 }
00513
00514 myargs = strdup(args);
00515
00516 if(myargs == NULL)
00517 flow_fatalerror("%s(%d) Unable to allocate memory!\n", file_name, file_line);
00518
00519 key = strtok(myargs, delim);
00520
00521 while(key != NULL)
00522 {
00523 value = strtok(NULL, delim);
00524
00525 if(!value)
00526 {
00527 flow_fatalerror("%s(%d) key %s has no value", file_name, file_line);
00528 }
00529
00530 FlowPSParseOption(config, file_name, file_line, key, value);
00531 key = strtok(NULL, delim);
00532 }
00533
00534 if(myargs)
00535 free(myargs);
00536
00537
00538 if(config->server_watchnet_ipv4 != NULL)
00539 {
00540 if((config->server_scanner_limit == 0) &&
00541 (config->server_ignore_limit == 0))
00542 {
00543 flow_fatalerror("A Server watchnet is set"
00544 " with no scanner or ignore limit\n"
00545 "Perhaps you should just remove"
00546 " the server-watchnet option\n");
00547
00548 }
00549
00550 }
00551 }
00552
00553 void FlowPSRestart(int signal, void *data)
00554 {
00555 return;
00556 }
00557
00558 void FlowPSCleanExit(int signal, void *data)
00559 {
00560 if(s_pkt)
00561 {
00562 free(s_pkt);
00563 s_pkt = NULL;
00564 }
00565
00566 if(!pv.quiet_flag)
00567 flowps_stats(&s_tracker);
00568
00569 flowps_destroy(&s_tracker);
00570 return;
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 int flowps_newflow_callback(FLOW_POSITION position, FLOW *flowp,
00606 int direction, time_t cur, FLOWPACKET *p)
00607 {
00608 TRACKER_POSITION tr_pos = TRACKER_ACTIVE;
00609 PS_TRACKER *pstp = &s_tracker;
00610 SCORE_ENTRY *current_entry = NULL;
00611 int ret, alert_flags, score;
00612 u_int8_t cflags;
00613 u_int32_t *address = &flowp->key.init_address;
00614
00615 if(!flowps_enabled())
00616 return 0;
00617
00618 if(s_debug > 5)
00619 {
00620 printf("DEBUG: callback %s:%d -> %s:%d\n",
00621 inet_ntoax(p->iph->ip_src.s_addr), p->sp,
00622 inet_ntoax(p->iph->ip_dst.s_addr), p->dp);
00623 }
00624
00625 if(position != FLOW_NEW)
00626 {
00627 #ifndef WIN32
00628 flow_printf("Wrong callback position for %s\n", __func__);
00629 #else
00630 flow_printf("Wrong callback position for %s(%d)\n", __FILE__, __LINE__);
00631 #endif
00632 return 0;
00633 }
00634
00635 if(flowps_is_ignored_ipv4(pstp,
00636 &flowp->key.init_address,
00637 &flowp->key.resp_address) == FLOW_SUCCESS)
00638 {
00639 return 0;
00640 }
00641
00642 if(IsTcpPacket(p))
00643 {
00644
00645
00646 cflags = GetTcpFlags(p);
00647 }
00648 else
00649 {
00650 cflags = 0;
00651 }
00652
00653
00654
00655
00656
00657
00658 if(flowps_get_score(pstp, flowp, cur,
00659 cflags, &score, &tr_pos) != FLOW_SUCCESS)
00660 {
00661 return -1;
00662 }
00663
00664 if(score == 0)
00665 {
00666 return 0;
00667 }
00668 else if(s_debug > 5)
00669 {
00670 flow_printf("new unique flow!\n");
00671 flowkey_print(&flowp->key);
00672 flow_printf("\n");
00673 }
00674
00675
00676 ret = flowps_find_entry(pstp, address, ¤t_entry);
00677
00678 if(ret == FLOW_NOTFOUND)
00679 {
00680 ret = flowps_add_entry(pstp, tr_pos, address, ¤t_entry);
00681
00682 if(ret != FLOW_SUCCESS)
00683 {
00684
00685 #ifndef WIN32
00686 flow_printf("flowps_add_entry check failed in %s\n", __func__);
00687 #else
00688 flow_printf("flowps_add_entry check failed in %s(%d)\n", __FILE__, __LINE__);
00689 #endif
00690 return 0;
00691 }
00692 }
00693 else if(ret != FLOW_SUCCESS)
00694 {
00695 #ifndef WIN32
00696 flow_printf("bad return for finding the entry %s\n", __func__);
00697 #else
00698 flow_printf("bad return for finding the entry %s(%d)\n", __FILE__, __LINE__);
00699 #endif
00700 return 0;
00701 }
00702
00703 flowps_sliding_winadj(¤t_entry->sliding_talker,
00704 cur,
00705 &pstp->config.limit_talker);
00706
00707 flowps_fixed_winadj(¤t_entry->fixed_talker,
00708 cur,
00709 &pstp->config.limit_talker);
00710
00711 flowps_sliding_winadj(¤t_entry->sliding_scanner,
00712 cur,
00713 &pstp->config.limit_scanner);
00714
00715 flowps_fixed_winadj(¤t_entry->fixed_scanner,
00716 cur,
00717 &pstp->config.limit_scanner);
00718
00719
00720 flowps_set_last_address(current_entry, flowp, cflags);
00721
00722
00723 if(s_debug > 5 && score > 1)
00724 {
00725 flow_printf("XXXX **** got a big old score(%d) because of [%s] -> %s\n",
00726 score, mktcpflag_str(cflags),
00727 inet_ntoa(*(struct in_addr *) (&flowp->key.resp_address)));
00728 flowps_entry_print(current_entry, address);
00729 flow_printf("\nXXXX ****\n");
00730 }
00731
00732 if(flowps_score_entry(pstp, current_entry, score, tr_pos,
00733 pstp->config.alert_once,
00734 &alert_flags) != FLOW_SUCCESS)
00735 {
00736 #ifndef WIN32
00737 flow_printf("bad return for finding the entry %s\n", __func__);
00738 #else
00739 flow_printf("bad return for finding the entry %s(%d)\n", __FILE__, __LINE__);
00740 #endif
00741 return 0;
00742 }
00743
00744
00745
00746
00747
00748 if(current_entry->position == TRACKER_ACTIVE && tr_pos == TRACKER_SCANNER)
00749 {
00750 int ret;
00751
00752
00753
00754
00755
00756
00757 ret = scoreboard_move(&pstp->table_scanner, &pstp->table_active, address);
00758
00759 if(ret != FLOW_SUCCESS)
00760 {
00761 flow_printf("Unable to move %s\n",inet_ntoa(*(struct in_addr *) address));
00762 return -1;
00763 }
00764 else
00765 {
00766
00767 current_entry->position = TRACKER_SCANNER;
00768 }
00769
00770 }
00771
00772 if(s_debug > 5)
00773 {
00774 if(tr_pos == TRACKER_SCANNER)
00775 {
00776 flow_printf("Found a tracker scanner!\n");
00777 flowps_entry_print(current_entry, address);
00778 }
00779 }
00780
00781 if(s_debug > 10)
00782 {
00783 flowps_entry_print(current_entry, address);
00784 }
00785
00786 if(alert_flags)
00787 {
00788
00789
00790
00791
00792
00793
00794 current_entry->flags |= alert_flags;
00795
00796
00797
00798 flowps_generate_flow_event(current_entry, p, address,
00799 pstp->config.output_mode, cur);
00800 }
00801
00802 return 0;
00803 }
00804
00805 static int flowps_generate_flow_event(SCORE_ENTRY *sep, FLOWPACKET *orig_packet,
00806 u_int32_t *address,
00807 FLOWPS_OUTPUT output_type,
00808 time_t cur)
00809 {
00810 Packet *p = NULL;
00811 char buf[1024 + 1];
00812 u_int32_t event_id;
00813 u_int32_t event_type;
00814
00815
00816 if(sep->flags & ALERT_FIXED_SCANNER)
00817 {
00818 event_type = FLOW_SCANNER_FIXED_ALERT;
00819 }
00820 else if(sep->flags & ALERT_SLIDING_SCANNER)
00821 {
00822 event_type = FLOW_SCANNER_SLIDING_ALERT;
00823 }
00824 else if(sep->flags & ALERT_SLIDING_TALKER)
00825 {
00826 event_type = FLOW_TALKER_SLIDING_ALERT;
00827 }
00828 else if(sep->flags & ALERT_FIXED_TALKER)
00829 {
00830 event_type = FLOW_TALKER_FIXED_ALERT;
00831 }
00832 else
00833 {
00834 return FLOW_EINVALID;
00835 }
00836
00837 switch(output_type)
00838 {
00839 case PKTKLUDGE:
00840
00841 p = flowps_mkpacket(sep, orig_packet, address, cur);
00842 case VARIABLEMSG:
00843 snprintf(buf, 1024,
00844 "Portscan detected from %s Talker(fixed: %u sliding: %u) Scanner(fixed: %u sliding: %u)",
00845 inet_ntoa(*(struct in_addr *) address),
00846 sep->fixed_talker.score, sep->sliding_talker.score,
00847 sep->fixed_scanner.score, sep->sliding_scanner.score);
00848 buf[1024] = '\0';
00849
00850
00851 event_id = GenerateSnortEvent(p,
00852 GENERATOR_FLOW_PORTSCAN,
00853 event_type,
00854 1,
00855 1,
00856 2,
00857 buf);
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 sep->event_id = event_id;
00868
00869
00870
00871
00872 sep->event_sec = packet_timeofday();
00873 }
00874
00875 return FLOW_SUCCESS;
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 static int score_entry_sprint(unsigned char *buf, int buflen, SCORE_ENTRY *sep, u_int32_t *address)
00892 {
00893 int printed = 0;
00894 int total_printed = 0;
00895 int remaining = buflen;
00896 int i;
00897
00898 if(buf && buflen > 0 && sep && address)
00899 {
00900 printed = snprintf(buf + total_printed,
00901 remaining,
00902 "Address: %s\n"
00903 "AT_SCORE: %u\n"
00904 "ST_SCORE: %u\n"
00905 "AS_SCORE: %u\n"
00906 "SS_SCORE: %u\n"
00907 "Total Connections: %u\n"
00908 "ScanFlags: 0x%x\n"
00909 "AT_STARTEND: %u %u\n"
00910 "ST_STARTEND: %u %u\n"
00911 "AS_STARTEND: %u %u\n"
00912 "SS_STARTEND: %u %u\n"
00913 "REF_SEC: %u\n"
00914 "REF_EVENT: %u\n",
00915 inet_ntoa(*(struct in_addr *)address),
00916 sep->fixed_talker.score,
00917 sep->sliding_talker.score,
00918 sep->fixed_scanner.score,
00919 sep->sliding_scanner.score,
00920 sep->connections_seen,
00921 sep->flags,
00922 (unsigned) sep->fixed_talker.start,
00923 (unsigned) sep->fixed_talker.ends,
00924 (unsigned) sep->sliding_talker.start,
00925 (unsigned) sep->sliding_talker.ends,
00926 (unsigned) sep->fixed_scanner.start,
00927 (unsigned) sep->fixed_scanner.ends,
00928 (unsigned) sep->sliding_scanner.start,
00929 (unsigned) sep->sliding_scanner.ends,
00930 (unsigned) sep->event_sec,
00931 sep->event_id);
00932
00933 if(printed <= 0)
00934 return -1;
00935
00936 remaining -= printed;
00937 total_printed += printed;
00938
00939 if(remaining <= 0)
00940 return -1;
00941
00942
00943 for(i=0; i < sep->connections_seen && i < FLOWPS_HOSTS_SIZE; i++)
00944 {
00945 CONN_ENTRY *cp = &sep->last_hosts[i];
00946
00947
00948 printed = snprintf(buf + total_printed,
00949 remaining,
00950 "ConnInfo: (%d:%s:%d Flags: %x)\n",
00951 cp->protocol,
00952 inet_ntoa(*(struct in_addr*) &cp->ip),
00953 cp->port,
00954 cp->cflags);
00955
00956 if(printed <= 0)
00957 return -1;
00958 remaining -= printed;
00959 total_printed += printed;
00960 if(remaining <= 0)
00961 return -1;
00962 }
00963
00964
00965 return total_printed;
00966 }
00967
00968 return -1;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 static Packet *flowps_mkpacket(SCORE_ENTRY *sep, FLOWPACKET *orig_packet, u_int32_t *address, time_t cur)
00989 {
00990 Packet *p = s_pkt;
00991 int len;
00992 u_int32_t dst_ip;
00993 unsigned short plen;
00994
00995 p->pkth->ts.tv_sec = cur;
00996
00997
00998 dst_ip = GetIPv4DstIp(orig_packet);
00999
01000 memcpy(&p->iph->ip_src.s_addr, address, 4);
01001 memcpy(&p->iph->ip_dst.s_addr, &dst_ip, 4);
01002
01003 len = score_entry_sprint(p->data, FLOWPSMAXPKTSIZE, sep, address);
01004
01005 if(len <= 0)
01006 {
01007
01008 return NULL;
01009 }
01010
01011 p->data[len] = '\0';
01012
01013
01014 plen = (len & 0xFFFF);
01015
01016 if((plen + IP_HEADER_LEN) < plen)
01017 {
01018
01019 return NULL;
01020 }
01021
01022 p->dsize = plen;
01023
01024 plen += IP_HEADER_LEN;
01025 p->iph->ip_len = htons(plen);
01026
01027 p->pkth->caplen = ETHERNET_HEADER_LEN + plen;
01028 p->pkth->len = ETHERNET_HEADER_LEN + plen;
01029
01030 return p;
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 static int flowps_init_pkt(void)
01042 {
01043 Packet *p = NULL;
01044 const char *flow_portscan_mac_addr = "MACDADDY";
01045 const char twiddlebytes = 2;
01046
01047 p = calloc(1,sizeof(Packet));
01048
01049 if(!p)
01050 {
01051 flow_fatalerror("Unable to alloc memory for the flow-portscan packet!\n");
01052 }
01053
01054 p->pkth = calloc(1,
01055 sizeof(struct pcap_pkthdr) + ETHERNET_HEADER_LEN
01056 + twiddlebytes + IP_MAXPACKET);
01057
01058 if(!p->pkth)
01059 {
01060 flow_fatalerror("Unable to alloc memory for the flow-portscan packet!\n");
01061 }
01062 else
01063 {
01064 p->pkth = (struct pcap_pkthdr *) (((u_int8_t *) p->pkth) + twiddlebytes);
01065 }
01066
01067 p->pkt = ((u_int8_t *)p->pkth) + sizeof(SnortPktHeader);
01068 p->eh = (EtherHdr *)((u_int8_t *)p->pkt);
01069 p->iph = (IPHdr *)((u_int8_t *)p->eh + ETHERNET_HEADER_LEN);
01070 p->data = ((u_int8_t *)p->iph) + sizeof(IPHdr);
01071
01072
01073
01074
01075
01076
01077
01078
01079 p->eh->ether_type = htons(0x0800);
01080 memcpy(p->eh->ether_dst, flow_portscan_mac_addr, 6);
01081 memcpy(p->eh->ether_src, flow_portscan_mac_addr, 6);
01082
01083 SET_IP_VER(p->iph, 0x4);
01084 SET_IP_HLEN(p->iph, 0x5);
01085
01086 p->iph->ip_proto = 0xFF;
01087 p->iph->ip_ttl = 0x00;
01088 p->iph->ip_len = 0x5;
01089 p->iph->ip_tos = 0x10;
01090
01091
01092 s_pkt = p;
01093
01094 return FLOW_SUCCESS;
01095 }