📄 snort.c
字号:
additional=&src_additional; }else if ( i==SNORT_DADDR ) { additional=&dst_additional; }else return 0; *additional=NULL; tmp=snort_head[i]; snort_head[i]=buf; for(ip=cur=tmp+1; ; cur++, len++) { if ( *cur==',' || *cur==']' || *cur==0 ) { if ( len > sizeof(buf) ) { mesg(M_WARN,"snort: ip in list too long!"); break; } memcpy(buf, ip, len-1); buf[len-1]=0; if ( snort_negate[i] && *cur==',' ) { struct criteria *foo; if ( !(foo=calloc(1, sizeof(*foo))) ) { ret=0; break; } if ( !(foo->args=strdup(buf)) ) { free(foo); ret=0; break; } foo->crit=NULL; foo->negate=1; foo->next=*additional; *additional=foo; }else{ if ( !steps[index].fn(index) ) { ret=0; break; } } if ( *cur==',') { ip=cur+1; len=0; continue; }else break; } } if ( *additional ) { cleanup_additional(*additional); *additional=NULL; } snort_head[i]=tmp; return ret;}/* See if a string is a variable if so, swap it */int snort_var_replace(char **ptr, int *n){ struct snort_var *v; if ( **ptr=='$' ) { if ( !(v=snort_var_find(*ptr+1)) ) { return 0; } *ptr=v->value; *n=v->negate; return 1; }else return 1;}int add_classification(char *name, char *prio){ unsigned int val; struct snort_class *c; if ( strtouint(prio, &val) ) { snprintf(estr,ELEN,"priorities must be numeric"); return 0; } if ( val & ~0xffUL ) { snprintf(estr,ELEN,"priority is out of range (0-255)"); return 0; } if ( (c=snort_class_find(name)) ) { snprintf(estr,ELEN,"re-definition of '%s' classification", name); return 0; } if ( !(c=calloc(1, sizeof(*c))) ) { snprintf(estr,ELEN,"calloc: %s", get_err()); return 0; } if ( !(c->name=strdup(name)) ) { snprintf(estr,ELEN,"strdup: %s", get_err()); free(c); return 0; } c->prio=(u_int8_t)val&0xff; c->next=c_list; c_list=c; return 1;}/* Deal with config lines in snort files */int snort_config(char *fn, int ln, char *line){ char *cur; char *str[3]; int i=0; int state=0; for(cur=line; *cur; cur++) { if ( *cur==':' ) { *cur=0; cur++; break; } } if ( strcmp(line, "classification") ) { mesg(M_WARN,"snort: %s:%i : ignoring '%s' config", fn, ln, line); return 1; } str[0]=cur; str[1]=NULL; str[2]=NULL; for(; ; cur++) { if ( terminator(*cur) ) { *cur=0; break; } if ( i>2 ) { continue; }else if ( state==0 ) { if ( !whitespace(*cur) ) { str[i++]=cur; state=1; } }else if ( state==1 ) { if ( *cur==',' ) { *cur=0; state=0; } } } if ( i<3 ) { snprintf(estr,ELEN, "malformed classification"); return 0; } return add_classification(str[0],str[2]); return 1;}/* Parse a 'var' line */int snort_var(char *fn, int ln, char *line){ char *key=NULL, *val=NULL; char *cur; struct snort_var *vn; int end=0; int negate=0, nneg=0; int state=0; for(cur=line; ; cur++) { if ( terminator(*cur) ) { *cur=0; break; } if ( state==0 ) { if ( *cur=='!' && key ) { negate=1; }else if ( !whitespace(*cur) ) { if ( !key ) { key=cur; state=1; }else{ if ( !val ) val=cur; continue; } } }else if ( state==1 ) { if ( whitespace(*cur) ) { *cur='\0'; state=0; end=1; } } } if ( !end ) { snprintf(estr, ELEN, "Incomplete line"); return 0; } /* TODO: This should be redundant */ if ( !snort_var_replace(&val, &nneg) ) { negate = negate ^ nneg; return 0; } if ( (vn=snort_var_find(key)) ) { char *snew; if ( !(snew=strdup(val)) ) { goto err_nomem; } free(vn->value); vn->value=snew; vn->negate=negate; }else{ if ( !(vn=malloc(sizeof(*vn))) ) { goto err_nomem; return 0; } if ( !(vn->name=strdup(key)) ) { free(vn); goto err_nomem; } if ( !(vn->value=strdup(val)) ) { free(vn->name); free(vn); goto err_nomem; } vn->negate=negate; vn->next=vars; vars=vn; } return 1; err_nomem: snprintf(estr, ELEN, "Out of memory for var '%s'", key); return 0;}/* Snort up each line of the config */int snort_line(char *fn, int ln, char *line){ struct criteria *s, *m; char *cur; int i; int end=0; int state=0; /* Zero all global values */ estr[0]=0; snort_sid=0; snort_rev=0; snort_prio=0; snort_prio_set=0; for(i=0; i<SNORT_MAX; i++) { snort_negate[i]=0; } /* State machine parser, parse out first 7 elements * seperated by any amount of whitespace ending in a '(' */ for(i=0, cur=line; ; cur++) { if ( terminator(*cur) ){ break; } if ( state == 0 ) { if ( *cur=='(' ) { if ( i==SNORT_MAX ) end=1; break; } if ( *cur=='!' ) { snort_negate[i]=1; }else if ( !whitespace(*cur) && *cur ) { if ( i >= SNORT_MAX ) break; snort_head[i]=cur; state=1; i++; } }else if ( state == 1 ) { if ( whitespace(*cur) ) { *cur='\0'; state=0; } } } /* Parse error */ if ( !end ) { snprintf(estr, ELEN, "Incomplete line"); return 0; } /* Its either "<-", "->" or "<>" */ if ( strlen(snort_head[SNORT_DIR]) !=2 ) { snprintf(estr, ELEN, "Invalid direction '%s'", snort_head[SNORT_DIR]); return 0; } /* Parse the rest of the rule */ se_head=NULL; snort_msg=NULL; snort_rate=0; snort_burst=0; if ( !snort_parse_body(++cur) ) return 0; /* Do variable substitutions */ if ( !snort_var_replace(&snort_head[SNORT_SADDR], &snort_negate[SNORT_SADDR]) ) return 0; if ( !snort_var_replace(&snort_head[SNORT_SPORT], &snort_negate[SNORT_SPORT]) ) return 0; if ( !snort_var_replace(&snort_head[SNORT_DADDR], &snort_negate[SNORT_DADDR]) ) return 0; if ( !snort_var_replace(&snort_head[SNORT_DPORT], &snort_negate[SNORT_DPORT]) ) return 0; /* Go forwards */ if ( snort_head[SNORT_DIR][1]=='>' ) { if ( !steps[0].fn(0) ) { return 0; } } /* Go backwards */ if ( snort_head[SNORT_DIR][0]=='<' ) { char *tadr, *tprt; int tna, tnp; /* Swap IPs and ports */ tadr=snort_head[SNORT_SADDR]; snort_head[SNORT_SADDR]=snort_head[SNORT_DADDR]; snort_head[SNORT_DADDR]=tadr; tna=snort_negate[SNORT_SADDR]; snort_negate[SNORT_SADDR]=snort_negate[SNORT_DADDR]; snort_negate[SNORT_SPORT]=tna; tprt=snort_head[SNORT_SPORT]; snort_head[SNORT_SPORT]=snort_head[SNORT_DPORT]; snort_head[SNORT_DPORT]=tprt; tnp=snort_negate[SNORT_SPORT]; snort_negate[SNORT_DADDR]=tna; snort_negate[SNORT_SPORT]=snort_negate[SNORT_DPORT]; if ( !steps[0].fn(0) ) { return 0; } } /* Free everything */ for(s=se_head; s; ) { struct criteria *tmp=s; for(m=s->modifier; m; ) { struct criteria *tmp=m; m=m->next; free(tmp); } s=s->next; free(tmp); } return 1;}/* Look at the first word of a snort line and decide * what kind of line it is and how to deal with it*/int snort_dispatch(char *fn, int ln, char *line){ struct skw *k; char *cur, *kw=NULL; int state=0; int end=0; for(cur=line; ;cur++) { if ( terminator(*cur) ) { break; } if ( state==0 ) { if ( !whitespace(*cur) ) { if ( !kw ) { kw=cur; state=1; }else{ break; } } }else if ( state==1 ) { if ( whitespace(*cur) ) { *cur=0; state=0; end=1; } } } if ( !end ) return 0; for(k=snort_keywords; k->name; k++) { if ( !strcmp(kw, k->name) ) return k->fn(fn, ln, cur); } snprintf(estr, ELEN, "Unsupported snort keyword: '%s'", kw); return 0;}/* Parse the snort file, line by line */int snort_run(char *fn){ FILE *f; char buf[SNORT_MAXLEN]; int line=0; if ( !fn ) return 0; if ( (f=fopen(fn, "r"))==NULL ) { mesg(M_ERR,"snort: error: %s: fopen(): %s", fn, get_err()); return 0; } /* iterate each line in the file */ while(fgets(buf, SNORT_MAXLEN, f)) { char *p=buf; line++; while ( *p && whitespace(*p) ) p++; if ( terminator(*p) || *p=='#' ) continue; if ( !snort_dispatch(fn, line, p) ) { mesg(M_ERR,"snort: %s:%i : %s", fn, line, estr); fclose(f); return 0; } } fclose(f); return 1;}struct parser snort_parser={ .name="snort", .load_file=snort_run,};int PLUGIN_PARSER (struct parser_api *p){ object_check(p); signature_rule=p->signature_rule; signature_criteria=p->signature_criteria; signature_modifier=p->signature_modifier; signature_alert=p->signature_alert; signature_commit=p->signature_commit; signature_abort=p->signature_abort; if ( !p->parser_add(&snort_parser) ) return PLUGIN_ERR_FAIL; return PLUGIN_ERR_OK;}int PLUGIN_INIT (struct plugin_in *in, struct plugin_out *out){ plugin_check(in, out); PLUGIN_ID("parser.snort", "Snort ruleset files"); PLUGIN_VERSION(2, 0); PLUGIN_AUTHOR("Gianni Tedesco", "gianni@scaramanga.co.uk"); PLUGIN_LICENSE("GPL"); memset(wspace_map, 0, sizeof(wspace_map)); wspace_map[' ']=1; wspace_map['\t']=1; wspace_map['\r']=2; wspace_map['\n']=2; return PLUGIN_ERR_OK;}int PLUGIN_UNLOAD (int code) { return PLUGIN_ERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -