⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snort.c

📁 Firestorm NIDS是一个性能非常高的网络入侵检测系统 (NIDS)。目前
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>#include <stdio.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <sys/unistd.h>#include <string.h>#include <firestorm.h>#include <args.h>#include <strtouint.h>#include <plugin.h>#include <cleanup.h>#include <packet.h>#include <alert.h>#include <signature.h>#include <parser.h>PLUGIN_STD_DEFS();/* Snort rulefile parser * Genrally the parsing is done with turing state machines, * It isn't _too_ hacky. * * TODO: * 	Full snort variable support * 	Multi-line support *//* Quick inline utility functions */static char wspace_map[256];#define terminator(x) (wspace_map[(unsigned char)x]==2)#define whitespace(x) (wspace_map[(unsigned char)x]==1)/* Maximum line length */#define SNORT_MAXLEN 8192/* Stuff we import */proc_sig_rule signature_rule;proc_sig_abort signature_abort;proc_sig_criteria signature_criteria;proc_sig_modifier signature_modifier;proc_sig_alert signature_alert;proc_sig_commit signature_commit;/* Snort variables */struct snort_var {	struct snort_var	*next;	char			*name;	char			*value;	int			negate;};struct snort_var *vars=NULL;struct snort_class {	struct snort_class *next;	char *name;	u_int8_t prio;};struct snort_class *c_list=NULL;int snort_line(char *, int, char *);int snort_var(char *, int, char *);int snort_config(char *, int, char *);/* Snort keywords */struct skw{	char *name;	int (*fn)(char *, int, char *);};struct skw snort_keywords[]={	{"alert", snort_line},	{"log", snort_line},#if 0	{"activate", NULL},	{"dynamic", NULL},	{"pass", NULL},#endif	{"config", snort_config},	{"var", snort_var},	{NULL, NULL}};/* Snort parsing variables */#define SNORT_PROTO 0#define SNORT_SADDR 1#define SNORT_SPORT 2#define SNORT_DIR 3#define SNORT_DADDR 4#define SNORT_DPORT 5#define SNORT_MAX 6char *snort_head[SNORT_MAX];int snort_negate[SNORT_MAX];struct criteria *se_head;struct criteria *src_additional;struct criteria *dst_additional;char *snort_msg;unsigned long snort_rate;unsigned long snort_burst;u_int32_t snort_prio;u_int32_t snort_prio_set;u_int32_t snort_sid, snort_rev;/* These are modifiers */char *snort_modifiers[]={	"nocase",	"offset",	"depth",	"regex",	NULL};/* Not implemented hacks */char *snort_hacks[]={	"reference",	"logto",	NULL};int snort_commit_rule(int index);int snort_iplist(int index);struct {	int var;	int(*fn)(int);}steps[]={	{SNORT_SADDR, snort_iplist},	{SNORT_DADDR, snort_iplist},	{0, snort_commit_rule},};/* Error string */#define ELEN 128char estr[ELEN];void cleanup_additional(struct criteria *x){	struct criteria *s;	for(s=x; s; ) {		struct criteria *tmp=s;		s=s->next;		if ( tmp->args ) free(tmp->args);		free(tmp);	}}struct snort_var *snort_var_find(char *key){	struct snort_var *ret;	for(ret=vars; ret; ret=ret->next) {		if ( !strcmp(key, ret->name) )			return ret;	}	snprintf(estr, ELEN, "snort var not found: $%s", key);	return NULL;}struct snort_class *snort_class_find(char *key){	struct snort_class *ret;	for(ret=c_list; ret; ret=ret->next) {		if ( !strcmp(key, ret->name) )			return ret;	}	return NULL;}int snort_parse_rate(char *str){	unsigned int num;	unsigned int d;	int i;	if ( (i=strtouint(str,&num))<0 ) goto err;	if ( i ) {		str+=i;		if ( *str++ != '/' ) goto err;		switch ( *str ) {		case 's':		case 'S':			d = RATE_SEC;			break;		case 'm':		case 'M':			d = RATE_MIN;			break;		case 'h':		case 'H':			d = RATE_HR;			break;		case 'd':		case 'D':			d = RATE_DAY;			break;		default:			goto err;		}	}else{		/* Seconds is the default */		d = RATE_SEC;	}	if ( num>d ) {		snprintf(estr,ELEN,"maximum granularity is 100/sec: %s", str);		return 0;	}	snort_rate=d/num;	return 1;err:	snprintf(estr,ELEN,"rate parse error for '%s'", str);	return 0;}int snort_addcrit(char *key, char *val, int negate){	int i;	struct criteria *se;	/* Snatch alert meta-data */	if ( !strcmp(key, "msg") ) {		snort_msg=val;		return 1;	}	if ( !strcmp(key, "sid") ) {		if ( strtouint(val, &snort_sid) ) {			snprintf(estr,ELEN,"invalid sid '%s'", val);			return 0;		}		return 1;	}	if ( !strcmp(key, "rev") ) {		if ( strtouint(val, &snort_rev) ) {			snprintf(estr,ELEN,"invalid rev '%s'", val);			return 0;		}		return 1;	}	if ( !strcmp(key, "priority") ) {		if ( strtouint(val, &snort_prio) ) {			snprintf(estr,ELEN,"invalid priority '%s'", val);			return 0;		}		if ( snort_prio & ~0xffUL ) {			snprintf(estr,ELEN,"priority is out of range (0-255)");			return 0;		}		snort_prio_set=1;		return 1;	}	if ( !strcmp(key, "classtype") ) {		struct snort_class *c;		if ( !(c=snort_class_find(val)) ) {			snprintf(estr,ELEN,"Unknown classtype '%s'", val);			return 0;		}		if ( !snort_prio_set ) snort_prio=c->prio;		return 1;	}	/* Rate limtiing */	if ( !strcmp(key, "rate") ) {		return snort_parse_rate(val);	}	if ( !strcmp(key, "burst") ) {		if ( strtouint(val, (unsigned int *)&snort_burst) ) {			snprintf(estr,ELEN,"invalid burst '%s'", val);			return 0;		}		return 1;	}	for(i=0; snort_hacks[i]; i++) {		if ( !strcmp(key, snort_hacks[i]) ) return 1;	}	/* Modifier options */	for(i=0; snort_modifiers[i]; i++) {		if ( !strcmp(key, snort_modifiers[i]) ) {			if ( !se_head ) return 0;			if ( !(se=calloc(1, sizeof(*se))) ) return 0;			se->crit=key;			se->args=val;			se->negate=negate;			se->next=se_head->modifier;			se_head->modifier=se;			return 1;		}	}	if ( !(se=calloc(1, sizeof(*se))) ) {		return 0;	}	se->next=NULL;	se->crit=key;	se->args=val;	se->negate=negate;	se->next=se_head;	se_head=se;	return 1;}/* Parse the body of a snort rule (the bit after the bracket) */#define zero_body() key=NULL; val=NULL; neg=0; state=0;int snort_parse_body(char *line){	char *key=NULL;	char *val=NULL;	int neg=0;	char *cur;	int state=0;	int inq=0;	int esc=0;	/* Snort state machine parser */	for(cur=line; ; cur++) {		if ( terminator(*cur) ) break;		if ( state==0 ) { /* Anywhere */			if ( !whitespace(*cur) ) {				key=cur;				state=1;			}else if ( *cur==')' ) {				*cur='\0';				break;			}		}else if ( state==1 ) { /* Inside a key */			if ( *cur==':' ) {				*cur='\0';				state=2;			}else if ( *cur==';' && *(cur-1)!='\\' ) {				*cur='\0';				val=NULL;				if ( !snort_addcrit(key, val, neg) ) return 0;				zero_body();			}		}else if ( state==2 ) { /* Between key and value */			if ( *cur=='!' ) {				neg=1;			}else if ( !whitespace(*cur) ) {				if ( *cur=='\"' ) {					inq=1;				}				val=cur + inq;				state=3;			}		}else if ( state==3 ) { /* In a value */			/* Enter quote marks */			if ( !inq && *cur=='\"' ) {				inq=1;				continue;			}			/* Allow missing end semicolon */			if ( !inq && *cur==')' ) {				if ( *(cur-1)=='\"' ) *(cur-1)='\0';				*cur='\0';				if ( !snort_addcrit(key, val, neg) ) return 0;				zero_body();				continue;			}			/* Check for escape chars */			if ( !esc && *cur=='\\' ) {				esc=1;				continue;			}			if ( inq && !esc && *cur=='\"' ) {				/* End quotes */				inq=0;			}else if ( !inq && !esc && *cur==';' ) {				/* End  */				if ( *(cur-1)=='\"' ) *(cur-1)='\0';				*cur='\0';				if ( !snort_addcrit(key, val, neg) ) return 0;				zero_body();			}else{				esc=0;			}		}	}	return 1;}/* Actually commit a rule into the signature * subsystem */int snort_commit_rule(int index){	struct criteria *s, *m;	struct rule *r;	/* Create a new rule */	if ( !(r=signature_rule(snort_head[SNORT_PROTO])) ) {		snprintf(estr, ELEN, "Unable to create new '%s' rule",			snort_head[SNORT_PROTO]);		return 0;	}	/* Alert stuff. Just use default alerting mechanism */	if ( !snort_sid ) mesg(M_WARN,"snort: rule has no sid: %s", snort_msg);	if ( !signature_alert(r, snort_msg,			snort_sid, snort_rev,			snort_rate, snort_burst,			(u_int8_t)snort_prio&0xff) ) {		snprintf(estr, ELEN, "Unable to set rule target");		goto abort;	}	/* Source and destination addresses */	if ( strcmp(snort_head[SNORT_SADDR], "any") && 		!signature_criteria(r, snort_negate[SNORT_SADDR],		"src", snort_head[SNORT_SADDR]) ){		snprintf(estr, ELEN, "Unable add head criteria to rule");		goto abort;	}	if ( strcmp(snort_head[SNORT_DADDR], "any") &&		!signature_criteria(r, snort_negate[SNORT_DADDR],		"dst", snort_head[SNORT_DADDR]) ){		snprintf(estr, ELEN, "Unable add head criteria to rule");		goto abort;	}	/* Ports */	if ( strcmp(snort_head[SNORT_SPORT], "any") ) {		if ( !signature_criteria(r, snort_negate[SNORT_SPORT],				"sport", snort_head[SNORT_SPORT]) ) {			snprintf(estr, ELEN, "Unable add head criteria to rule");			goto abort;		}	}	if ( strcmp(snort_head[SNORT_DPORT], "any") ) {		if ( !signature_criteria(r, snort_negate[SNORT_DPORT],				"dport", snort_head[SNORT_DPORT]) ) {			snprintf(estr, ELEN, "Unable add head criteria to rule");			goto abort;		}	}	/* Additional source and destination addresses */	for(s=src_additional; s; s=s->next) {		if ( !signature_criteria(r, s->negate, "src", s->args) ){			snprintf(estr, ELEN, "Unable add head criteria to rule");			goto abort;		}	}	for(s=dst_additional; s; s=s->next) {		if ( !signature_criteria(r, s->negate, "dst", s->args) ){			snprintf(estr, ELEN, "Unable add head criteria to rule");			goto abort;		}	}	/* And all the options... */	for(s=se_head; s; s=s->next) {		if ( !signature_criteria(r, s->negate, s->crit, s->args) ) {			goto abort2;		}		for(m=s->modifier; m; m=m->next) {			if ( !signature_modifier(r, m->negate, m->crit, m->args) ) {				goto abort2;			}		}	}	/* lets go */	if ( !signature_commit(r) ) {		snprintf(estr, ELEN, "Rule failed to commit: %s",			snort_msg);		goto abort;	}	return 1;abort2:	snprintf(estr, ELEN, "Unable add '%s' to rule", s->crit);abort:	signature_abort(r);	return 0;}int snort_iplist(int index){	char buf[128];	char *cur, *ip, *tmp;	size_t len=1;	int ret=1;	int i=steps[index++].var;	struct criteria **additional;	if ( snort_head[i][0]!='[' ) return steps[index].fn(index);	if ( i==SNORT_SADDR ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -