--- ratproxy/Makefile 2008-06-10 06:44:28.000000000 -0500 +++ ratproxymod/Makefile 2008-11-06 16:36:22.000000000 -0600 @@ -21,7 +21,7 @@ PROGNAME = ratproxy CFLAGS = -Wall -O3 -Wno-pointer-sign -D_GNU_SOURCE -LDFLAGS = -lcrypto -lssl +LDFLAGS = -lcrypto -lssl -lsqlite3 all: $(PROGNAME) flare-check --- ratproxy/ratproxy.c 2008-07-03 01:27:15.000000000 -0500 +++ ratproxymod/ratproxy.c 2008-11-06 16:36:24.000000000 -0600 @@ -43,6 +43,9 @@ #include #include +/* MSF Wmap - ET loWNOISE et[]metasploit.com */ +#include + #include "config.h" #include "types.h" #include "debug.h" @@ -75,8 +78,11 @@ _u8* use_proxy; /* Upstream proxy */ _u8* trace_dir; /* Trace directory */ +_u8* db_file; /* Sqlite3 DB */ _u32 proxy_port = 8080; /* Upstream proxy port */ -_u8 use_len; /* Use length, not cksum */ +_u8 use_len; /* Use length, not cksum */ + +_u8 ip_addr[18]; static FILE* outfile; /* Output file descriptor */ @@ -90,6 +96,7 @@ " -p port - listen on a custom TCP port (default: 8080)\n" " -d domain - analyze requests to specified domains only (default: all)\n" " -P host:port - use upstream proxy for all requests (format host:port)\n" + " -b dbfile - Sqlite3 wmap file\n" " -r - accept remote connections (default: 127.0.0.1 only)\n" " -l - use response length, not checksum, for identity check\n" " -2 - perform two, not one, page identity check\n" @@ -111,7 +118,8 @@ "Example settings suitable for most tests:\n" " 1) Low verbosity : -v -w -d -lfscm\n" " 2) High verbosity : -v -w -d -lextifscgjm\n" - " 3) Active testing : -v -w -d -XClfscm\n\n" + " 3) Active testing : -v -w -d -XClfscm\n" + " 4) Wmap : -v -b \n" "Multiple -d options are allowed. Consult the documentation for more.\n", argv0); @@ -538,12 +546,23 @@ static _u8 dump_fn[1024]; static _u8 dumped_already; +static _u8 db_dump_fn[1024]; /* Save trace data to file, if requested. */ static _u8* save_trace(struct http_request* req, struct http_response* res) { _s32 f; _u32 i; + _u32 lenh; + _u32 reslenh; FILE* out; + _u8 *zErrMsg = 0; + _u8 *zTail; + _u32 rc; + sqlite3 *db; + sqlite3_stmt *pStmt; + static _u8 reqhbuf[1024]; + static _u8* reqh; + static _u8* resh; if (!trace_dir) return "-"; @@ -551,6 +570,109 @@ if (dumped_already) return dump_fn; dumped_already = 1; + /* Sqlite3 Wmap format*/ + + if (db_file) { + + lenh=0; + for (i=0;ih.c;i++){ + sprintf(reqhbuf,"%s: %s\n", req->h.v1[i], req->h.v2[i]); + lenh = lenh+strlen(reqhbuf); + } + + reqh = malloc(lenh + 1); + if (!reqh) fatal("out of memory"); + + strcpy(reqh,""); + + for (i=0;ih.c;i++){ + sprintf(reqhbuf,"%s: %s\n", req->h.v1[i], req->h.v2[i]); + strcat(reqh,reqhbuf); + } + + /* Resp headers*/ + reslenh=0; + for (i=0;ih.c;i++){ + sprintf(reqhbuf,"%s: %s\n", res->h.v1[i], res->h.v2[i]); + reslenh = reslenh+strlen(reqhbuf); + } + + resh = malloc(reslenh + 1); + if (!resh) fatal("out of memory"); + + strcpy(resh,""); + + for (i=0;ih.c;i++){ + sprintf(reqhbuf,"%s: %s\n", res->h.v1[i], res->h.v2[i]); + strcat(resh,reqhbuf); + } + + /*db*/ + + sprintf(db_dump_fn,"%s/%s",trace_dir,db_file); + + rc = sqlite3_open(db_dump_fn, &db); + if( rc ){ + fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + exit(1); + } + + + _u8 retry,kr; + + retry =1; + kr=0; + while(retry){ + rc = sqlite3_prepare( db, + "INSERT INTO " + " requests(host,port,ssl,meth,path,headers,query,body,respcode,resphead,response,created) " + "VALUES(?,?,?,?,?,?,?,?,?,?,?,?);", + -1, &pStmt, &zTail); + + if( rc!=SQLITE_OK ){ + //fprintf(stderr, "SQL error: %s\n", zErrMsg); + //fprintf(stderr, "SQL error: retries %d\n", kr++); + sqlite3_free(zErrMsg); + retry = 1; + } + else{ + if(rc==SQLITE_OK){ + //fprintf(stderr, "SQL OK: retries %d\n", kr++); + + sqlite3_bind_text(pStmt, 1, ip_addr, -1, SQLITE_STATIC); + sqlite3_bind_int(pStmt, 2, req->port); + sqlite3_bind_int(pStmt, 3, req->from_ssl); + sqlite3_bind_text(pStmt, 4, req->method, -1, SQLITE_STATIC); + sqlite3_bind_text(pStmt, 5, req->path, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 6, reqh, lenh, SQLITE_STATIC); + sqlite3_bind_text(pStmt, 7, req->query, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 8, req->payload,req->payload_len , SQLITE_STATIC); + sqlite3_bind_int(pStmt, 9, res->code); + sqlite3_bind_blob(pStmt, 10, resh,reslenh, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 11, res->payload, res->payload_len, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 12, "", -1, SQLITE_STATIC); + rc = sqlite3_step(pStmt); + if ( rc!=SQLITE_DONE ) { + //blah + } + else{ + sqlite3_finalize(pStmt); + //fprintf(stderr, "SQL FINALIZE: retries %d\n", kr++); + retry =0; + } + } + } + } + + free(reqh); + free(resh); + sqlite3_close(db); + + } + else { + /* Normal save*/ + sprintf(dump_fn,"%.512s/%08x-%04x.trace",trace_dir,(_u32)time(0),getpid()); f = open(dump_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); @@ -594,6 +716,7 @@ fclose(out); close(f); + } return dump_fn; } @@ -1653,7 +1776,7 @@ debug("ratproxy version " VERSION " by \n"); - while ((opt = getopt(argc,argv,"+w:v:p:d:P:itxgjmafske2clXCr")) > 0) + while ((opt = getopt(argc,argv,"+w:v:p:d:P:b:itxgjmafske2clXCr")) > 0) switch (opt) { case 'w': { @@ -1761,6 +1884,11 @@ use_any = 1; break; + case 'b': + if (db_file) fatal("multiple -b options make no sense"); + db_file = optarg; + break; + default: usage(argv[0]); } --- ratproxy/http.c 2008-06-10 07:28:26.000000000 -0500 +++ ratproxymod/http.c 2008-11-06 16:36:24.000000000 -0600 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,8 @@ static _u8 srv_buf[MAXLINE], /* libc IO buffers */ cli_buf[MAXLINE]; +extern _u8 ip_addr[18]; + /* Read a single line of HTTP headers, strip whitespaces */ static _u8* grab_line(FILE* where) { @@ -657,7 +660,10 @@ struct hostent* he; _s32 ss; - if (!(he = gethostbyname(host)) || !(he->h_addr_list[0])) + he = gethostbyname(host); + strncpy(ip_addr,inet_ntoa(*((struct in_addr *)he->h_addr_list[0])),18); + + if (!(he) || !(he->h_addr_list[0])) http_error(client,"Unable to find target host",0); ss = socket(PF_INET, SOCK_STREAM, 0);