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

📄 spp_anomsensor.c

📁 该源码是用C语言编写的,实现网络入侵检测系统的功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/*========================================================================*//*========================== SpadeAdapt2 module ==========================*//*========================================================================*//* Given an hourly alert target count (or target fraction) and a length of   time, this module tries to keep the reporting threshold at a level that   would produce that number of alerts (or fraction of total reports) in an   hour based on what has been observed in the past.  When the report threshold   is updated, it is based in equal parts on observations from the short term,   middle term, and long term (at least for these that have been observed).    The user can specify the time period for observations, the number of those   that make up the short term (NS), the number of short terms that make up the   medium term (NM), and the number of medium terms that make up the long term   (NL).  The short term component of the threshold is defined to be the   average of the kth and (k+1)st highest anomaly scores in the last NS   complete periods of observation, where k is number of anamoly reports that   should occur in the observation period assuming a uniform rate.  The middle   term component is the average of the last NM special short term components.    The special short term components are the ones that are multiples of NS if   labeled with the number of observation periods that had completed when it   was calculated (i.e., #NS, #2NS, #3NS, etc.); these have the property that   they are based entirely on distinct measurements.  The long term component   is based on the last NL medium term componenets, including the current one.    For each of the components, if there have been less than the specified   number of constituant parts (but there has been at least one complete one),   what is observed thus far is used.  To accomadate the varying rates of   packets fairly, the observation period is based on a count of packets.  This   count is the product of the specified observation period and the average   packet rate.*//* snort config file line:	preprocessor spade-adapt2: [ <target-spec> [ <obs-time> [ <NS> [ <NM> [ <NL> ]]]]]	where:	  <target-spec> if >= 1, is the number of alerts to aim for in an hour, and	    if < 1, is the fraction of packets to aim for (default 0.01)	  <obs-time> is the number of minutes in an observation period (default 15)	  <NS> is the number of observation periods that make up the short term	    (default 4)	  <NM> is the number of short terms in the medium term (default 24)	  <NL> is the number of medium terms in the long term (default 7)*//* global-scope variables used in the adapt2 module */// the first and second arguments from the config linedouble adapt2_targetspec,obsper;// the 3rd, 4th, and 5th argsint NS,NM,NL;// the current target based on adapt2_targetspecint adapt2_target;// latest middle and long term componentsdouble mid_anom_comp,long_anom_comp;// representation of an array of observation lists, the heads and tailsdll_double **obslists_head,**obslists_tail;// an array of the (0-based) size of these listsint *obslists_size;// the number of complete observation periodsint obsper_count;// arrays of short and medium term components used for calculating other componentsdouble *recScomps,*recMcomps;/* Spade adapt2 module init function:     set up the adapt2 module per its args and register its preprocessor function */void SpadeAdapt2Init(u_char *args){	int i;	if (adapting) {		fprintf(stderr,"Anomoly sensor threshold adapting repeadly specified, ignoring later specification: %s\n",args);		return;	}	adapting= 1;	pp_active++;	need_anom= 1;    /* parse the argument list from the rules file */    ParseSpadeAdapt2Args(args);    /* Set the preprocessor function into the function list */    AddFuncToPreprocList(PreprocSpadeAdapt2);	obslists_head= (dll_double **)malloc(NS * sizeof(dll_double *));	obslists_tail= (dll_double **)malloc(NS * sizeof(dll_double *));	obslists_size= (int *)malloc(NS * sizeof(int));	for (i= 0; i < NS; i++) {		obslists_head[i]= new_dlink(0.0);		obslists_tail[i]= new_dlink(0.0);		obslists_head[i]->next= obslists_tail[i];		obslists_tail[i]->prev= obslists_head[i];		obslists_size[i]= 1;	}	obsper_count= 0;	recScomps= (double *)malloc(NM * sizeof(double));	recMcomps= (double *)malloc(NL * sizeof(double));		if (as_debug) printf("Preprocessor: SpadeAdapt2 Initialized\n");}/* Spade 'spade-adapt2' argument parsing function  */void ParseSpadeAdapt2Args(char *args){    char **toks;    int numToks;    toks = mSplit(args, " ", 20, &numToks, '\\');   	if (numToks > 0) {		adapt2_targetspec= atof(toks[0]); /* if >= 1, is an hourly count, else is a fraction of total packets */	} else {		adapt2_targetspec= 0.01;	}	if (numToks > 1) {		obsper= atof(toks[1])*60.0; /* basic observation/adjust time in mins, converted to secs */	} else {		obsper= 15.0*60.0;	}	/* 10000 packets per hour is our pure guess as to the rate of packets.	   Is there a better way to figure out how many packets to note for our	   first interval when we want a percent of packets? */	adapt2_target= (int)floor(0.5+ (adapt2_targetspec >= 1 ? adapt2_targetspec*(obsper/3600.0) : ((10000/3600.0)*obsper)*adapt2_targetspec));	if (adapt2_target==0) adapt2_target= 1; /* ensure at least 1 long */	if (numToks > 2) {		NS= atoi(toks[2]); /* how many of the previous go into the time observation of ideal wait and the recent portion of the adapted weight */	} else {		NS= 4;	}	if (numToks > 3) {		NM= atoi(toks[3]); /* how many of the previous go into an average to determine the middle portion of the adapted weight */	} else {		NM= 24;	}	if (numToks > 4) {		NL= atoi(toks[4]); /* how many of the previous go into an average to determine the long-term portion of the adapted weight */	} else {		NL= 7;	}	if (as_debug) printf("adapt2 target is %d\n",adapt2_target);	if (as_debug) printf("%2f seconds in obs per1; %d of these in recent; %d 2's in middle; %d in long\n",obsper,NS,NM,NL);}/* Spade adapt2 module routine that is called with each packet */void PreprocSpadeAdapt2(Packet *p){	/* see if time to adjust the rate and if so, do so, and reset */	size_t packet_time= p->pkth->ts.tv_sec;	dll_double *new,*prev,*l;	int i;	// the start time of the current observation period	static time_t obsper_start=(time_t)0;	// the number of packets thus far in this observation	static int obscount=0;	// the last calculated average packet count per component;	// used to figure out when to adjust the threshold;	// set high initially to be sure to get a correct value before doing this	static double ppc= 100000000.0;	// obsper_count % NS, which obslist to add to	static int obslist_new_slot= 0;		if (packet_time > (obsper_start + obsper)) {		static int rec_int_count;		if (obsper_start == 0) { /* first packet */			obsper_start= packet_time;			rec_int_count= 0;			recent_alert_count= 0;		} else { /* time to update ppc */			rec_int_count++;			if (as_debug) {				printf("%d alerts in time period %d (of %d packets)\n",recent_alert_count,rec_int_count,recent_packets);			}			ppc= tot_packets/(double)rec_int_count;			obsper_start+= (long)obsper;			if (as_debug) {				static int last_repcount;				printf("End of time period %d: ppc is now %.2f\n",rec_int_count,ppc);				printf("  %d alerts in last time period; ave alert rate is %.2f\n",(alert_count-last_repcount),(float)alert_count/(float)rec_int_count);				last_repcount= alert_count;			}						adapt2_target= (int)floor(0.5+ (adapt2_targetspec >= 1 ? adapt2_targetspec*(obsper/3600.0) : adapt2_targetspec*ppc));			if (adapt2_target==0) adapt2_target= 1; /* ensure at least 1 long */			if (as_debug) printf("new target is %d\n",adapt2_target);						if (obsper_count == 0) {				obsper_count++;				obslist_new_slot= obsper_count % NS;				if (obslists_size[0] > adapt2_target) { /* remove excess */					for (i= adapt2_target, l=obslists_head[0]; i < obslists_size[0]; i++,l=l->next);					l->prev->next= NULL;					l->prev= NULL;					free_dlinks(obslists_head[0]);					obslists_head[0]= l;				}				set_new_threshold((obslists_head[0]->val + obslists_head[0]->next->val)/2.0);				if (as_debug) printf("-> initial adapted threshold is %.5f\n",report_anom_thres);				obscount= 0;				recent_packets= 0;				recent_alert_count= 0;			}		}	}		if (record_maybe_skip(p)) return;	/* accepted packets only past here; anom score is last_anom_score */	obscount++;		if (obscount > ppc) {		if (as_debug) {			printf("%d alerts at end of packet period #%d (of %d)\n",recent_alert_count,obslist_new_slot,recent_packets);		}				set_new_threshold(calc_new_thresh());		if (as_debug) printf("-> new threshold is %.5f\n",report_anom_thres);				obsper_count++;		obslist_new_slot= obsper_count % NS;		reset_obslist(obslist_new_slot);		obscount= 0;		recent_packets= 0;		recent_alert_count= 0;	}	if (obslists_size[obslist_new_slot] < adapt2_target) {		new= new_dlink(last_anom_score);		obslists_size[obslist_new_slot]++;	} else if (last_anom_score > obslists_head[obslist_new_slot]->val) {		if (last_anom_score < obslists_head[obslist_new_slot]->next->val) {			obslists_head[obslist_new_slot]->val= last_anom_score; /* can just replace first in place*/			return;		}		new= obslists_head[obslist_new_slot];		new->val= last_anom_score;		obslists_head[obslist_new_slot]= obslists_head[obslist_new_slot]->next;		new->next->prev= NULL;	} else {		return;	}	for (l=obslists_head[obslist_new_slot]->next; l != NULL && last_anom_score > l->val; l=l->next);	/* add between l->prev and l */	prev= (l == NULL) ? obslists_tail[obslist_new_slot] : l->prev;	prev->next= new;	new->prev= prev;	new->next= l;	if (l == NULL) {		obslists_tail[obslist_new_slot]= new;	} else {		l->prev= new;	}}double calc_new_thresh() {	static int per2_count=0,per3_count=0; // the count of period 2 and 3 instances	double rec_anom_comp= thresh_from_obslists();	if (as_debug) printf("* New recent anom observation (#%d) is %.5f\n",obsper_count,rec_anom_comp);	if (obsper_count < (NS-1)) {		return rec_anom_comp; /* haven't observed mid or long yet */	}	if (((obsper_count+1) % NS) == 0) { /* time to add new mid */		recScomps[per2_count % NM]= rec_anom_comp;		if (as_debug) printf("recScomps[%d]:= %.5f\n",per2_count % NM,rec_anom_comp);		per2_count++;		mid_anom_comp= anom_ave(recScomps,((per2_count < NM)?per2_count:NM));		if (as_debug) printf("** New mid anom component (#%d) is %.5f\n",per2_count-1,mid_anom_comp);		if (per2_count < (NM-1)) {			return (rec_anom_comp+mid_anom_comp)/2.0; /* haven't observed long yet */		}		if ((per2_count % NM) == 0) { /* time to add new long */			recMcomps[per3_count % NL]= mid_anom_comp;			if (as_debug) printf("recMcomps[%d]:= %.5f\n",per3_count % NL,mid_anom_comp);			per3_count++;				long_anom_comp= anom_ave(recMcomps,((per3_count < NL)?per3_count:NL));			if (as_debug) printf("*** New long anom component (#%d) is %.5f\n",per3_count-1,long_anom_comp);		}	}	if (per2_count < NM) {		return (rec_anom_comp+mid_anom_comp)/2.0; /* haven't observed long yet */	}	return (rec_anom_comp+mid_anom_comp+long_anom_comp)/3.0;}double thresh_from_obslists() {	dll_double **pos= (dll_double **)malloc(NS * sizeof(dll_double *)); 	int i,c,maxpos=-1;	double max,last_score=0.0,before_last_score=0.0;	if (as_debug > 1) {		dll_double *l;		printf("thresh_from_obslists: finding score that is #%d highest in:\n",adapt2_target);		for (i= 0; i < NS; i++) {			printf("  slot %d: %.5f",i,obslists_head[i]->val);			for (l=obslists_head[i]->next; l != NULL; l=l->next) {				printf(" -> %.5f",l->val);			}			printf("\n");		}	}	for (i= 0; i < NS; i++) {		pos[i]= obslists_tail[i];	}	for (c= 1; c <= adapt2_target+1; c++) {		max= -1;		for (i= 0; i < NS; i++) {			if (pos[i] != NULL) {				if (max < pos[i]->val) {					max= pos[i]->val;					maxpos= i;				}							}		}		if (max == -1) return last_score; /* should only happen if we don't		                                    have enough packets recorded */		pos[maxpos]= pos[maxpos]->prev;		before_last_score= last_score;		last_score= max; /* in case this is the last */	}	return (before_last_score+last_score)/2.0;}double anom_ave(double a[],int size) {	double sum= 0.0;	int i;	if (as_debug) {		printf("anom_ave: taking average of (%.5f",a[0]);		for (i=1; i < size; i++) printf(",%.5f",a[i]);		printf(")\n");	}	for (i=0; i < size; i++) sum+= a[i];	return sum/(double)size;}void reset_obslist(int slot) {	dll_double *first= obslists_head[slot];	dll_double *second= first->next;	if (second->next != NULL) free_dlinks(second->next);	first->val= 0.0;	second->val= 0.0;	second->next= NULL;	obslists_tail[slot]= second;	obslists_size[slot]= 1;}/*========================================================================*//*========================== SpadeAdapt3 module ==========================*//*========================================================================*//* Given an hourly alert target count (or target fraction) and a length of   time, this module tries to keep the reporting threshold at a level that   would produce that number of alerts (or fraction of total reports) in an   hour based on what has been observed in the past.  ...*//* snort config file line:	preprocessor spade-adapt3: [ <target-spec> [ <obs-time> [ <num-obs>]]]	where:	  <target-spec> if >= 1, is the number of alerts to aim for in an hour, and	    if < 1, is the fraction of packets to aim for (default 0.01)	  <obs-time> is the number of minutes in an observation period (default 60)	  <num-obs> is the number of observation periods to average over (default 168)*//* global-scope variables used in the Adapt3 module */// the first and second arguments from the config linedouble adapt3_targetspec,adapt3_obsper;// the 3rd argint NO;// the current target based on adapt3_targetspec

⌨️ 快捷键说明

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