📄 log.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <ctype.h>#include <time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <firestorm.h>#include <packet.h>#include <args.h>#include <cleanup.h>#include <alert.h>#include <signature.h>#include <decode.h>#include <target.h>#include <plugin.h>#include <capture.h>PLUGIN_STD_DEFS();static char *state_str[]={ "CLOSED", "ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT1", "FIN_WAIT2", "TCP_TIME_WAIT", "TCP_CLOSE", "TCP_CLOSE_WAIT", "TCP_LAST_ACK", "TCP_LISTEN", "TCP_CLOSING"};#include <cleanup.h>/* Imported functions */proc_args_parse args_parse;proc_decode_proto decode_proto;struct proto *ipproto=NULL;struct proto *http_proto=NULL;/* Private data structure */struct log_priv { char *fn; int fd; char *buf; size_t buflen;};void log_http(char *buf, int len, struct http_session *h){ /* 28 = 14+12+2 = extraneous bits of string */ if ( len < 28+h->uri_len+h->method_len ) return; memcpy(buf, " http_method='", 14); buf+=14; memcpy(buf, h->method, h->method_len); buf+=h->method_len; memcpy(buf, "' http_uri='", 12); buf+=12; memcpy(buf, h->uri, h->uri_len); buf+=h->uri_len; memcpy(buf, "'", 2);}/* Open a file */int log_openfile(void *priv){ struct log_priv *p=priv; if ( (p->fd=open(p->fn, O_WRONLY|O_APPEND|O_CREAT, 0640))<0 ) { mesg(M_ERR,"log: %s: open(): %s", p->fn, get_err()); free(p); return 0; } return 1;}/* Configuration callbacks */int cb_file(struct arg *a, void *priv){ struct log_priv *p=priv; return (p->fn=strdup(a->val.v_str)) ? 1 : 0;}int log_a(struct generator *gen, struct packet *pkt, struct alert *a, void *priv){ union { struct pkt_tcphdr *tcph; struct pkt_udphdr *udph; struct pkt_icmphdr *icmph; }u; u_int32_t flags; struct log_priv *p=priv; struct pkt_iphdr *iph; char sip[16], dip[16]; static char pbuf[4096]; struct in_addr ina; unsigned int l; int ret; /* TCP stuff */ char tcpflags[]="FSRPAU12"; char disp[9]; int n, x; struct tcp_session *s; int s_state, c_state; if ( !pkt ) return 0; for(l=0; l<pkt->llen; l++) { if ( pkt->layer[l].proto==ipproto ) goto found; } mesg(M_CRIT,"log: No IP header found"); return 1;found: iph=pkt->layer[l].h.ip; if ( l+1 >= pkt->llen ) { pbuf[0]=0; goto just_ip; } u.tcph=pkt->layer[l+1].h.tcp; flags=pkt->layer[l+1].flags; /* Convert IPs to strings */ ina.s_addr=iph->saddr; strncpy(sip, inet_ntoa(ina), 15); sip[15]=0; ina.s_addr=iph->daddr; strncpy(dip, inet_ntoa(ina), 15); dip[15]=0; switch(iph->protocol) { case 6: for(n=0,x=1; n<8; n++, x*=2) { if ( u.tcph->flags.flags & x ){ disp[n]=tcpflags[n]; }else{ disp[n]='*'; } }disp[8]='\0'; if ( (s=pkt->layer[l+1].session) ) { s_state=s->server.state; c_state=s->client.state; }else{ s_state=0; c_state=0; } ret=snprintf(pbuf, sizeof(pbuf), "spt=%u dpt=%u flags=%s " "from=%s server=%s client=%s ", ntohs(u.tcph->sport)&0xffff, ntohs(u.tcph->dport)&0xffff, disp, (flags&FLAG_TCP_2SVR) ? "client" : "server", state_str[s_state], state_str[c_state]); if ( ret<0 ) { pbuf[0]=0; break; } if ( l+2<pkt->llen && pkt->layer[l+2].proto==http_proto && pkt->layer[l+2].session ) { log_http(pbuf+ret, sizeof(pbuf)-ret, pkt->layer[l+2].session); } break; case 17: snprintf(pbuf, sizeof(pbuf), "spt=%u dpt=%u", ntohs(u.udph->sport)&0xffff, ntohs(u.udph->dport)&0xffff); break; case 1: snprintf(pbuf, sizeof(pbuf), "type=%u code=%u", u.icmph->type&0xff, u.icmph->code&0xff); break; default: pbuf[0]=0; }just_ip: ret=snprintf(p->buf, p->buflen, "%lu.%.6lu alert=%s sig=%u.%u priority=%u " "src=%s dst=%s proto=%u %s : %s\n", pkt->time.tv_sec, pkt->time.tv_usec, gen->name, a->sid, a->rev, a->priority, sip, dip, iph->protocol&0xff, pbuf, a->alert); if ( ret>0 ) { if ( write(p->fd, p->buf, ret)<0 ) { return 0; } }else{ mesg(M_CRIT,"log: error formatting log"); return 0; } return 1;}int log_v(char *args, void **ptr){ struct log_priv *priv; struct arg log_args[]={ {"file", ARGTYPE_STRING, cb_file}, {NULL, ARGTYPE_NOP, NULL}, }; if ( !ipproto && !(ipproto=decode_proto("ip")) ) { mesg(M_ERR,"log: IP protocol must be loaded " "to use log output"); return 0; } if ( !http_proto && !(http_proto=decode_proto("http")) ) { mesg(M_ERR,"log: HTTP protocol must be loaded " "to use log output"); return 0; } if ( !(priv=calloc(1, sizeof(*priv))) ) return 0; priv->buflen=4096; if ( args ) { switch ( args_parse(log_args, args, priv) ) { case -1: mesg(M_ERR,"log: parse error: %s", args); case 0: /* fall through */ free(priv); return 0; default: break; } } if ( !(priv->buf=malloc(priv->buflen)) ) { mesg(M_ERR,"log: malloc(): %s", get_err()); free(priv); return 0; } if ( !priv->fn ) { /* Use stdout */ priv->fd=1; }else{ /* Open the file */ if ( !log_openfile(priv) ) { free(priv); return 0; } } *ptr=priv; return 1;}void log_h(void *priv){ struct log_priv *p=priv; if ( !p ) return; if ( p->fd>2 ) { if ( fsync(p->fd) ) mesg(M_CRIT,"log: fsync(): %s", get_err()); if ( close(p->fd) ) mesg(M_CRIT,"log: close(): %s", get_err()); if ( !log_openfile(p) ) { mesg(M_CRIT,"log: error reopening logfile"); return; } }}void log_c(void *priv){ struct log_priv *p=priv; if ( !p ) return; /* Don't close if we are stdin/stdout */ if ( p->fd>2 ) { if ( fsync(p->fd) ) mesg(M_CRIT,"log: fsync(): %s", get_err()); if ( close(p->fd) ) mesg(M_CRIT,"log: close(): %s", get_err()); } free(p);}struct target log_t[]={ target_init("log", log_a, log_v, log_h, log_c), target_null()};int PLUGIN_TARGET (struct target_api *t){ object_check(t); args_parse=t->args_parse; if ( !t->target_add(log_t) ) 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("target.log", "TCP/IP based log plugin"); PLUGIN_VERSION(0,1); PLUGIN_AUTHOR("Gianni Tedesco", "gianni@scaramanga.co.uk"); PLUGIN_LICENSE("GPL"); if ( !(decode_proto=in->import("decode.proto")) ) { return PLUGIN_ERR_OBJECT; } return PLUGIN_ERR_OK;}int PLUGIN_UNLOAD (int code) { return PLUGIN_ERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -