From: Keven T. <byt...@sh...> - 2009-01-15 23:11:11
|
Greetings to all. I've attached a bunch of patches to sshguard as below. These consist of the following fixes/features: 1) Added support for snort IDS style syslog "alerts" (offending hosts) to sshguard_services.h, attack_parser.h, attack_parser.y, and attack_scanner.l. I think everything I've done here is valid, though I'm not familiar with Flex so the attack_scanner.l code might be slightly whacked. It does, however, compile and actually works. If anyone wants to run over the relevant code in attack_scanner.l, here's a sample Snort syslog output (IP addresses are just random numbers): Jan 15 15:49:20 sensor snort[11588]: [1:402:8] ICMP Destination Unreachable Port Unreachable [Classification: Misc activity] [Priority: 3]: {ICMP} 212.79.65.90 -> 96.56.224.81 The format of it is pretty simple: <syslog crap> [NUMBER:NUMBER:NUMBER] <more text> {WORD} SOURCE_IP -> DEST_IP Where SOURCE_IP is the /only/ thing that should matter, since that is the originating IP that the detected attack came from. This is what I / tried/ to write the attack_scanner.l code to do, and it seems to work just fine. 2) Modified sshguard.c to properly support abuse thresholds of "1". This is primarily for the above Snort modifications (block-on-sight), though I believe it applies to parsing of any other logs. For whatever reason, sshguard_options.c was setup to accept -a 1, but sshguard.c effectively ignored the first abuse sighting regardless of what -a was set to. The fix basically involves removing one line and changing another, so that first-time abusers are blocked on sight if -a is set to 1 (block on 1st abuse). 3) Modified sshguard_options.c so that values < -p 2 are ignored and usage is printed. When -p is set to 1 (which really doesn't make sense, but whatever), sshguard_options.c accepted this and caused the line: sleep(1 + random() % (opts.pardon_threshold/2)) to immediately bomb out with a FP error. Limiting -p's minimum to 2 obviously solves this problem. Again, I don't know why -p would be set to such a low value, but it's a crash I came across regardless and fixed. Patches are below. -KT *** ./sshguard_original/src/attack_parser.h 2009-01-15 16:01:38.000000000 -0700 --- ./sshguard/src/attack_parser.h 2009-01-15 15:59:43.000000000 -0700 *************** *** 70,76 **** PROFTPD_LOGINERR_PREF = 286, PROFTPD_LOGINERR_SUFF = 287, PUREFTPD_LOGINERR_PREF = 288, ! PUREFTPD_LOGINERR_SUFF = 289 }; #endif /* Tokens. */ --- 70,78 ---- PROFTPD_LOGINERR_PREF = 286, PROFTPD_LOGINERR_SUFF = 287, PUREFTPD_LOGINERR_PREF = 288, ! PUREFTPD_LOGINERR_SUFF = 289, ! SNORTIDS_ALERTERR_PREF = 290, ! SNORTIDS_ALERTERR_SUFF = 291 }; #endif /* Tokens. */ *************** *** 106,111 **** --- 108,115 ---- #define PROFTPD_LOGINERR_SUFF 287 #define PUREFTPD_LOGINERR_PREF 288 #define PUREFTPD_LOGINERR_SUFF 289 + #define SNORTIDS_ALERTERR_PREF 290 + #define SNORTIDS_ALERTERR_SUFF 291 *** ./sshguard_original/src/attack_parser.y 2009-01-15 16:01:38.000000000 -0700 --- ./sshguard/src/attack_parser.y 2009-01-15 14:50:04.000000000 -0700 *************** *** 49,54 **** --- 49,56 ---- %token PROFTPD_LOGINERR_PREF PROFTPD_LOGINERR_SUFF /* PureFTPd */ %token PUREFTPD_LOGINERR_PREF PUREFTPD_LOGINERR_SUFF + /* Snort IDS */ + %token SNORTIDS_ALERTERR_PREF SNORTIDS_ALERTERR_SUFF %% *************** *** 100,105 **** --- 102,108 ---- | freebsdftpdmsg { parsed_attack.service = SERVICES_FREEBSDFTPD; } | proftpdmsg { parsed_attack.service = SERVICES_PROFTPD; } | pureftpdmsg { parsed_attack.service = SERVICES_PUREFTPD; } + | snortidsmsg { parsed_attack.service = SERVICES_SNORTIDS; } ; /* an address */ *************** *** 212,217 **** --- 215,225 ---- PUREFTPD_LOGINERR_PREF addr PUREFTPD_LOGINERR_SUFF ; + /* attach rules for Snort IDS */ + snortidsmsg: + SNORTIDS_ALERTERR_PREF addr SNORTIDS_ALERTERR_SUFF + ; + %% void yyerror(char *msg) { /* do nothing */ } *** ./sshguard_original/src/attack_scanner.l 2009-01-15 16:01:38.000000000 -0700 --- ./sshguard/src/attack_scanner.l 2009-01-15 15:12:40.000000000 -0700 *************** *** 63,69 **** %option debug %array ! %s ssh_notallowed ssh_loginerr ssh_reversemap dovecot_loginerr cyrusimap_loginerr freebsdftpd_loginerr proftpd_loginerr pureftpd_loginerr MONTH (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) DAYNO [1-9][0-9]? --- 63,69 ---- %option debug %array ! %s ssh_notallowed ssh_loginerr ssh_reversemap dovecot_loginerr cyrusimap_loginerr freebsdftpd_loginerr proftpd_loginerr pureftpd_loginerr snortids_alerterr MONTH (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) DAYNO [1-9][0-9]? *************** *** 146,151 **** --- 146,155 ---- "("[^@] + "@" { BEGIN (pureftpd_loginerr); return PUREFTPD_LOGINERR_PREF; } <pureftpd_loginerr>") [WARNING] Authentication failed for user ".+ { BEGIN(INITIAL); return PUREFTPD_LOGINERR_SUFF; } + /* Snort IDS */ + "["{NUMBER }":"{NUMBER }":"{NUMBER }"]".*"{"{WORD}"}" { BEGIN(snortids_alerterr); return SNORTIDS_ALERTERR_PREF; } + <snortids_alerterr>"->".+ { BEGIN(INITIAL); return SNORTIDS_ALERTERR_SUFF; } + /** COMMON-USE TOKENS do not touch these **/ /* an IPv4 address */ *** ./sshguard_original/src/sshguard_services.h 2009-01-15 16:01:38.000000000 -0700 --- ./sshguard/src/sshguard_services.h 2009-01-15 15:59:42.000000000 -0700 *************** *** 51,54 **** --- 51,57 ---- /* Pure-FTPd */ #define SERVICES_PUREFTPD 320 + /* Snort IDS */ + #define SERVICES_SNORTIDS 330 + #endif *** ./sshguard_original/src/sshguard.c 2009-01-15 16:01:38.000000000 -0700 --- ./sshguard/src/sshguard.c 2009-01-15 16:08:24.000000000 -0700 *************** *** 287,294 **** tmpent = malloc(sizeof(attacker_t)); attackerinit(tmpent, & attack); list_append(&limbo, tmpent); - - return; } --- 287,292 ---- *************** *** 395,401 **** ipe->attack.address.kind = attack->address.kind; ipe->attack.service = attack->service; ipe->whenfirst = ipe->whenlast = time(NULL); ! ipe->numhits = 1; } void purge_limbo_stale(void) { --- 393,399 ---- ipe->attack.address.kind = attack->address.kind; ipe->attack.service = attack->service; ipe->whenfirst = ipe->whenlast = time(NULL); ! ipe->numhits = 0; } void purge_limbo_stale(void) { *** ./sshguard_original/src/sshguard_options.c 2009-01-15 16:01:38.000000000 -0700 --- ./sshguard/src/sshguard_options.c 2009-01-15 15:49:12.000000000 -0700 *************** *** 65,72 **** break; case 'p': /* pardon threshold interval */ opts.pardon_threshold = strtol(optarg, (char **)NULL, 10); ! if (opts.pardon_threshold < 1) { ! fprintf(stderr, "Doesn't make sense to have a pardon time lower than 1 second. Terminating.\n"); return -1; } break; --- 65,72 ---- break; case 'p': /* pardon threshold interval */ opts.pardon_threshold = strtol(optarg, (char **)NULL, 10); ! if (opts.pardon_threshold < 2) { ! fprintf(stderr, "Doesn't make sense to have a pardon time lower than 2 second. Terminating.\n"); return -1; } break; |