📄 http.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <firestorm.h>#include <args.h>#include <packet.h>#include <plugin.h>#include <alert.h>#include <signature.h>#include <decode.h>#include <preproc.h>#include <netinet/in.h>PLUGIN_STD_DEFS();proc_dispatch dispatch;static struct http_session http_noflow;int http_dprint(struct layer *l, char *buf, int buflen){ struct http_session *h; char *obuf=buf; if ( !(h=l->session) ) return snprintf(buf, buflen, "No session info"); /* 27 = 13+12+2 = bits of strings */ if ( buflen < 27+h->uri_len+h->method_len ) return snprintf(buf, buflen, "buffer too small"); memcpy(buf, "http_method='", 13); buf+=13; 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); /* including trailing null */ return (buf-obuf);}int http_serialize(struct packet *p, unsigned int i, char *buf, int len){ struct layer *l=&p->layer[i]; struct http_session *s=(struct http_session *)l->session; struct http_serial *f=(struct http_serial *)buf; if ( len < sizeof(struct http_serial) ) return -1; f->uri=htonl(s->uri - (char *)l->h.raw); f->uri_len=htonl(s->uri_len); f->method=htonl(s->method - (char *)l->h.raw); f->method_len=htonl(s->method_len); return sizeof(*f);}/* Remember: this data is un-trusted so validate it! */void *http_deserialize(struct packet *p, unsigned int i, char *buf, int len){ struct http_session *s; struct http_serial *f=(struct http_serial *)buf; struct layer *l=&p->layer[i]; u_int32_t plen; if ( len < sizeof(*f) ) return NULL; plen=(char *)p->end - (char *)l->h.raw; /* validate the input */ if ( plen < htonl(f->uri)+htonl(f->uri_len) ) return NULL; if ( plen < htonl(f->method)+htonl(f->method_len) ) return NULL; if ( !(s=calloc(1, sizeof(*s))) ) return NULL; s->uri=l->h.raw + ntohl(f->uri); s->uri_len=ntohl(f->uri_len); s->method=l->h.raw + ntohl(f->method); s->method_len=ntohl(f->method_len); return s;}/* Really crappy HTTP request parsing routine. */int http_decode_request(struct http_session *h, char *p, char *end){ char *tok; int state=0; memset(h, 0, sizeof(*h)); for( tok=p; p<end; p++ ) { /* Bail if we find binary characters */ if ( *p!='\r' && *p!='\n' && (*p<32 || *p&0x80) ) { return 0; } switch ( state ) { case 0: if ( *p==' ' ) { state=1; h->method=tok; h->method_len=(size_t)(p-tok); tok=p; break; } break; case 1: if ( *p!=' ' ) { tok=p; state=2; } break; case 2: if ( *p==' ' ) { state=3; h->uri=tok; h->uri_len=(size_t)(p-tok); tok=p; } break; } }#if 0 write(1, h->method, h->method_len); write(1, " -> ", 4); write(1, h->uri, h->uri_len); write(1, "\n", 1);#endif return 0;}int http_decode(struct packet *p) { struct http_session *h; char *begin, *end; int ret=0; /* Only parse HTTP requests for now */ if ( !(p->layer[p->llen-1].flags & FLAG_TCP_2SVR) ) goto done; /* If we can't do session state tracking then * at least we can try parse it as a request */ if ( !(h=((struct tcp_session *) p->layer[p->llen-1].session)->flow) ) { h=&http_noflow; } /* Work out payload boundaries */ begin=p->layer[p->llen].h.raw; end=p->layer[p->llen-2].h.raw + p->layer[p->llen-2].h.ip->tot_len; /* end>p->end hould never happen */ if ( end<=begin || end > (char *)p->end ) { goto done; } /* Actually do the HTTP request decode */ if ( http_decode_request(h, begin, end)<0 ) { ret=-1; goto done; } p->layer[p->llen++].session=h; dispatch(p); return 0;done: if ( p->layer[p->llen].h.raw<p->end ) p->layer[p->llen++].proto=NULL; dispatch(p); return ret;}struct proto http_p={ .name="http", .sdecode=http_decode, .print=http_dprint, .state_len=sizeof(struct http_session), .serialize=http_serialize, .deserialize=http_deserialize, .free=free,};struct proto_req http_r[]={ proto_request("tcp", __constant_htons(80)), proto_request("tcp", __constant_htons(3128)), proto_request("tcp", __constant_htons(8080)), null_request()};int PLUGIN_DECODE (struct decode_api *d){ int ok=0; object_check(d); dispatch=d->dispatch; ok+=d->decode_add(&http_p, http_r); return (ok) ? PLUGIN_ERR_OK : PLUGIN_ERR_FAIL;}int PLUGIN_INIT (struct plugin_in *in, struct plugin_out *out){ plugin_check(in, out); PLUGIN_ID("decode.http", "Hyper-text Transfer Protocol"); PLUGIN_VERSION(0, 1); PLUGIN_AUTHOR("Gianni Tedesco", "gianni@scaramanga.co.uk"); PLUGIN_LICENSE("GPL"); return PLUGIN_ERR_OK;}int PLUGIN_UNLOAD (int code) { return PLUGIN_ERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -