int main (int argc, char **argv) { struct spike * spike_instance; int port; char *host; char buffer[1500000]; /* Get some parameters */ if (argc != 3) { printf("Usage: ./lighttpd_fuzz <host> <port>\n"); exit(2); } host = argv[1]; port = atoi(argv[2]); if (port < 1) { fprintf(stderr, "Invalid port %d, using default of 9999\n", port); port = 9999; } /* Set up Spike */ spike_instance = new_spike(); if (spike_instance == NULL) { fprintf(stderr, "Malloc failed trying to allocate a spike.\n"); exit(-1); } setspike(spike_instance); /* Print something so it's clear that we've started */ printf("Spike initialized\n"); /* Initialize the fuzzing and reset the fuzz variables */ s_init_fuzzing(); s_resetfuzzvariable(); /* The original generic_send_tcp had some nice ways to shortcut in to specific variables. I'm skipping that for now to better learn how this works */ while (!s_didlastvariable()) { s_resetfuzzstring(); while(!s_didlastfuzzstring()) { spike_clear(); /* Connect via TCP */ spike_connect_tcp(host, port); if (spike_send() < 0) { fprintf(stderr, "Could not send data \n"); } /* Do some stuff: This is the core commands of the fuzz script */ s_readline(); //print received line from server s_string("GET "); s_string_variable("/cgi.pl"); s_string(" HTTP/1.0"); s_string("\n"); s_string_variable("COMMAND"); //send fuzzed string spike_close_tcp(); //printf("%s", s_get_databuf()); /*see, the thing is that the spike is not guaranteed to be null terminated, so just a plain printf on the s_get_databuf() is ill-advised.*/ memset(buffer,0x00,sizeof(buffer)); if (s_get_size()>2500) memcpy(buffer,s_get_databuf(),2500); else memcpy(buffer,s_get_databuf(),s_get_size()); printf("Request:\n%.2500s\nEndRequest\n",buffer); s_incrementfuzzstring(); } /* while !s_didlastfuzzstring() */ s_incrementfuzzvariable(); } /* while !s_didlastvariable() */ return 0; }
int main (int argc, char ** argv) { char * target; char buffer[1500000]; int port; char *pipename; unsigned char uid[2]; unsigned char tid[2]; unsigned char fid[2]; #define SAVESLOTS 5 unsigned char *savedbuf[SAVESLOTS]; unsigned int savedsize[SAVESLOTS]; int currentsaveslot; struct spike * our_spike; unsigned long retval; unsigned int number_of_tries, number_of_items; unsigned short function_number; int i,j,s; unsigned int r; int sent; int randval; int msrpcdo; char * login = NULL, * password = NULL; #define ARGCNEEDED 9 if (argc < ARGCNEEDED) { printf("Argc=%d not %d\n",argc,ARGCNEEDED); usage(); } target=argv[1]; printf("Target is %s\r\n",argv[1]); msrpcdo=-1; if (getenv("MSRPC_DO")) { msrpcdo=atoi(getenv("MSRPC_DO")); } function_number=atoi(argv[6]); printf("Hitting function number %d\n",function_number); number_of_tries=atoi(argv[7]); number_of_items=atoi(argv[8]); if(argc > ARGCNEEDED) { if(argc != ARGCNEEDED + 2) { usage(); } login = argv[9]; password = argv[10]; } port=445; pipename=argv[2]; for (s=0;s<SAVESLOTS; s++) { savedbuf[s]=malloc(0); savedsize[s]=0; } currentsaveslot=0; signal(SIGPIPE,sig_pipe); if (getenv("RANDVAL")) randval=atoi(getenv("RANDVAL")); else randval=getpid(); printf("MSRPC_DO=%d and RANDVAL=%d\n",msrpcdo,randval); srand(randval); printf("Initialized random with %d\n",randval); fprintf(stderr,"Initialized random with %d\n",randval); for (i=0; i<number_of_tries; i++) { printf("Try Number %d on procedure %d\n",i,function_number); fflush(0); our_spike=new_spike(); if (our_spike==NULL) { fprintf(stderr,"Malloc failed trying to allocate a spike.\r\n"); exit(-1); } /*this really only gets called once*/ s_init_fuzzing(); setspike(our_spike); /*do unicode the MS way*/ s_set_unicode(1); s_smb_negotiate(login, password); sent=spike_send_tcp(target,port); if (sent==0 || caught_sigpipe) { /*this means the server went down!*/ if (sent==0) fprintf(stderr,"We killed it! \n"); else { fprintf(stderr,"We caught sigpipe!\n"); fprintf(stdout,"We caught sigpipe!\n"); } for (s=0; s<SAVESLOTS;s++) { fprintf(stderr,"Current Save Slot = %d\n",currentsaveslot); fprintf(stderr,"Printing save slot %d\n",s); #if 0 pretty_print(savedbuf[s],savedsize[s]); #endif } fprintf(stderr,"Done.\n"); if (sent==0) { //printf("Was not able to connect: Sleeping...\n"); //sleep(100); //sleep(59999); } //exit(1); } else { #ifdef SAVEBUF /*we always malloc it with something*/ free(savedbuf[currentsaveslot]); #endif } s_fd_wait(); memset(buffer,0,sizeof(buffer)); alarm(1); retval=read(getcurrentspike()->fd,buffer,1500); alarm(0); if (retval==-1) { printf("couldn't smb negotiate continuing\n"); spike_close_tcp(); spike_free(our_spike); continue; } if (buffer[9]!=0x00) { printf("Error value when trying to negotiate an SMB connection: %x\n",buffer[10]); spike_close_tcp(); spike_free(our_spike); continue; } spike_clear(); /*do the smb session startup*/ s_smb_session_setup(login, password); spike_send(); s_fd_wait(); memset(buffer,0,sizeof(buffer)); alarm(1); retval=read(getcurrentspike()->fd,buffer,1500); alarm(0); if (retval==-1) { printf("couldn't smb session startup continuing\n"); spike_close_tcp(); spike_free(our_spike); continue; } if (*(unsigned int *)(buffer+9)!=0x00000000) { printf("Error value when trying to start up an SMB session: %8.8x\n",*(unsigned int *)(buffer+9)); if (0x00080001==(*(unsigned int *)(buffer+9))) { printf ("Error returned was out of memory.\n"); } spike_close_tcp(); spike_free(our_spike); continue; } memcpy(uid,buffer+32,2); printf("Uid is %x%x\n",uid[0],uid[1]); /*done with smb session startup*/ spike_clear(); /*start IPC$ connection */ s_smb_ipc_connect(uid); spike_send(); s_fd_wait(); memset(buffer,0,sizeof(buffer)); alarm(1); retval=read(getcurrentspike()->fd,buffer,1500); alarm(0); if (retval==-1) { printf("couldn't smb session IPC$ startup continuing\n"); spike_close_tcp(); spike_free(our_spike); continue; } if (*(unsigned int *)(buffer+9)!=0x00000000) { printf("Error value when trying to start up an SMB IPC$ session: %8.8x\n",*(unsigned int *)(buffer+9)); spike_close_tcp(); spike_free(our_spike); continue; } memcpy(tid,buffer+32-4,2); printf("Tree id is %x%x\n",uid[0],uid[1]); /*done with IPC$ connection*/ /* do the NT Create AndX Request */ spike_clear(); s_nt_createandx(tid,uid,pipename); spike_send(); printf ("Sent NT AndX request\n"); s_fd_wait(); memset(buffer,0,sizeof(buffer)); alarm(1); retval=read(getcurrentspike()->fd,buffer,1500); alarm(0); if (retval==-1) { printf("couldn't NT Create AndX - continuing\n"); spike_close_tcp(); spike_free(our_spike); continue; } if (*(unsigned int *)(buffer+9)!=0x00000000) { printf("Error value when trying to start up an NT AndX: %8.8x\n",ntohl(*(unsigned int *)(buffer+9))); if (0x220000c0==ntohl(*(unsigned int *)(buffer+9))) { printf("Error returned was Access Denied\n"); } else { if (0xac0000c0==ntohl(*(unsigned int *)(buffer+9))) { printf("Error returned was Pipe Not Available\n"); } if (0x340000c0==ntohl((*(unsigned int *)(buffer+9)))) { printf ("Error returned was File Not Found.\n"); } } spike_close_tcp(); spike_free(our_spike); continue; } memcpy(fid,buffer+42,2); printf("File id is %x%x\n",uid[0],uid[1]); /*done with the NT Create AndX Request*/ spike_clear(); /*Send the Netbios and SMB header for the DCE-RPC packet*/ s_smbheader(fid,uid,tid); /*i is sent in just to keep incrementing*/ /*hardcoded the transfer syntax and syntax version of 2...they are always the same*/ s_dce_bind(argv[3], /*GUID "Interface" */ "8a885d04-1ceb-11c9-9fe8-08002b104860", /*syntax - always the same*/ i, atoi(argv[4]), /*interface version major*/ atoi(argv[5]), /*interface version minor, usually zero*/ 2); /*syntax version*/ s_block_end("DCEFragLength"); /*ALWAYS HAVE TO DO*/ /*phew! :>*/ /*had to add this for SMB block*/ s_block_end("smbblock"); s_block_end("bytecount"); sent=spike_send(); s_fd_wait(); /*clear the response*/ alarm(1); fcntl(our_spike->fd, F_SETFL, O_NONBLOCK); retval=read(our_spike->fd,buffer,1500); if (retval==-1 && 0) { printf ("couldn't read, continuing\n"); perror("read()"); spike_close_tcp(); spike_free(our_spike); continue; } alarm(0); /*the offset of the DCE within the SMB stuff*/ #define DCEOFFSET 60 if (buffer[2+DCEOFFSET]!=DCE_BIND_ACK) { printf("Warning, did not recieve bind_ack! Instead got 0x%x\n",buffer[2+DCEOFFSET]); if (buffer[2+DCEOFFSET]==0x0d) printf("I believe 0x0d is provider reject - check your version number\n"); if (buffer[2+DCEOFFSET]==0x00) { /*this means the server went down!*/ fprintf(stderr,"We almost killed it! \n"); fprintf(stderr,"Current Save Slot = %d\n",currentsaveslot); fprintf(stderr,"Printing save slot %d\n",s); #if 0 pretty_print(savedbuf[currentsaveslot],savedsize[currentsaveslot]); #endif fprintf(stderr,"Done.\n"); } } /*send first packet*/ spike_clear(); s_smb_dce_call(4,buffer,0,fid,uid,tid); s_smbdce_doreadx(fid,uid,tid,buffer,sizeof(buffer)); /*assume bind success...*/ /*send a random packet*/ spike_clear(); /*2nd arg is alloc hint*/ /*s_dce_call_header(1, 5300, function_number,1,1);*/ r=0+(unsigned int) (number_of_items*1.0*rand()/(RAND_MAX+1.0)); // r=number_of_items; /*EntryNameSyntax*/ s_intelword(3); /*I think this is a "pointer"*/ s_binary("70 b7 23 00"); /*EntryName*/ //s_dce_unistring("/.:/bob/bob"); s_dce_unistring(s_get_random_fuzzstring()); //s_dce_unistring("/.:/6"); /*some null pointers*/ s_intelword(0); s_intelword(0); s_intelword(0); /* push_random_msrpc_thing(); push_random_msrpc_thing(); */ s_intelword(0x64); s_intelword(0x1c20); /*test*/ /*r=1;*/ for (j=0; j<r+1; j++) { //push_valid_thing(); //push_random_msrpc_thing(); } printf("Pushing %u things with total size of %u\n",(unsigned int)r+1,(unsigned int)s_get_size()); /*save it off in our saved buffers*/ if (currentsaveslot==SAVESLOTS-1) { currentsaveslot=0; } else { currentsaveslot++; } #ifdef SAVEBUF savedbuf[currentsaveslot]=malloc(s_get_size()); memcpy(savedbuf[currentsaveslot],s_get_databuf(),s_get_size()); savedsize[currentsaveslot]=s_get_size(); #endif /* Localization of bugs: only actually send the packet if we eithar do not have a MSRPC_DO value or if our current i is less than that number Change the < to an == when you get close. */ if (msrpcdo==-1 || i==msrpcdo) { printf("Sending request\n"); /*read from 4 first...*/ pretty_print(s_get_databuf(),s_get_size()); if (!s_smb_dce_call(function_number,s_get_databuf(),s_get_size(),fid,uid,tid)) { printf("do_dce_call failed\n"); spike_free(our_spike); return 0; } } s_fd_wait(); /*clear the response*/ memset(buffer,0,sizeof(buffer)); //alarm(1); //s_fd_wait(); //retval=read(getcurrentspike()->fd,buffer,1500); s_smbdce_doreadx(fid,uid,tid,buffer,sizeof(buffer)); //s_fd_wait(); //retval=read(getcurrentspike()->fd,buffer,1500); alarm(0); if (retval==-1) { printf("continuing\n"); spike_close_tcp(); spike_free(our_spike); continue; } if (buffer[2+DCEOFFSET]==DCE_FAULT) { printf("Recieved DCE_FAULT packet. As expected.\n"); } else { printf("Recived response packet with type %x\n",buffer[2+DCEOFFSET]); printf("Type 0x0c is BIND_ACK\n"); } if (retval==-1) { printf("dce call: Interesting - server closed socket!\n"); //return 0; } spike_close_tcp(); /*close the socket*/ spike_clear(); spike_free(our_spike); } return 0; }
int main (int argc, char ** argv) { int first; char * target; char buffer[150000]; char requestbuffer[150000]; int port; char * file; char * directory; struct spike * our_spike; unsigned long retval; int notfin; char * extention; char * method; int firstfuzz; int fuzzvarnum,fuzzstrnum; /*for fuzz variable count*/ int SKIPVARIABLES,SKIPFUZZSTR; if (argc!=9) { usage(); } target=argv[1]; printf("Target is %s\r\n",argv[1]); port=atoi(argv[2]); method = argv[3]; directory = argv [4]; file = argv[5]; extention=argv[6]; SKIPVARIABLES=atoi(argv[7]); SKIPFUZZSTR=atoi(argv[8]); fuzzvarnum=0; fuzzstrnum=0; our_spike=new_spike(); s_init_fuzzing(); /*sheesh.*/ signal(SIGPIPE,SIG_IGN); if (our_spike==NULL) { fprintf(stderr,"Malloc failed trying to allocate a spike.\r\n"); exit(-1); } setspike(our_spike); /*during s_variable push, if fuzzstring is == currentfuzzstring then set didlastfuzzstring. If fuzzvariable is == current variable, set didlastfuzzvariable*/ /*zeroth fuzz variable is first variable*/ s_resetfuzzvariable(); /* fuzzvarnum=0; fuzzstrnum=0; */ firstfuzz=1; while (!s_didlastvariable()) { s_resetfuzzstring(); /*zeroth fuzz string is no change*/ if (firstfuzz) { /*zeroth fuzz string is no change*/ /*see below for why we have this if statement and loop*/ if (fuzzvarnum<SKIPVARIABLES ) { for (fuzzvarnum=0; fuzzvarnum<SKIPVARIABLES; fuzzvarnum++) { s_incrementfuzzvariable(); } } /*here is another part of where we implement the ability to jump to a particular place in the fuzzing*/ if (fuzzstrnum<SKIPFUZZSTR) { for (fuzzstrnum=0; fuzzstrnum<SKIPFUZZSTR; fuzzstrnum++) { s_incrementfuzzstring(); } } firstfuzz=0; } else { /*we reset this here so every new variable gets a new count*/ fuzzstrnum=0; } while(!s_didlastfuzzstring()) { printf("Fuzzing Variable %d:%d\n",fuzzvarnum,fuzzstrnum); spike_clear(); /*reset this*/ /*controls when we put an ampersand or not*/ s_setfirstvariable(); s_string_variable(method); s_string(" "); s_string(directory); s_string_variable(file); s_string(extention); /*url arguments*/ #ifdef USEARGS s_string("?"); s_string_variable("View"); s_string_variable("="); s_string_variable("Logon"); #endif #ifdef RTSP s_string(" RTSP/1.0"); #else s_string(" HTTP/1.1"); #endif s_string_variable(""); s_string("\r\n"); #ifdef RTSP //a simple per-request sequence number s_string("CSeq: "); s_string_variable("1"); s_string("\r\n"); s_string("Session: "); s_string_variable("260778254-1"); s_string("\r\n"); s_string("PlayerStats: "); s_string_variable("Stat3"); s_string(":"); s_string_variable("331"); s_string("|"); s_string_variable("0"); s_string("|"); s_string_variable("STOP"); s_string("|"); s_string(";]["); s_string_variable("Stat4"); s_string(":"); s_string_variable("0"); s_string(" "); s_string("0 0 0"); s_string("|"); s_string_variable("0"); s_string("|"); s_string_variable("0"); s_string("|"); s_string(" 0 2]\r\n"); #endif #ifndef RTSP s_string("Referer: http://localhost/"); s_string_variable("bob"); s_string("\r\n"); s_string("Content-Type: "); s_string_variable("application/x-www-form-urlencoded"); #ifdef XML s_string_variable("application/xml"); #endif s_string("\r\n"); s_string("Connection: "); s_string_variable("close"); #ifdef WEBDAV s_string_variable("TE"); #endif s_string("\r\n"); #ifdef WEBDAV s_string("TE: "); s_string_variable("trailers"); s_string("\r\n"); s_string("Depth: "); s_string_variable("0"); s_string("\r\n"); #endif //Cookie: JSESSIONID=2CB3ED5F0D71E3C6CD504705BAFD67E0.tomcatinstance1 s_string("Cookie: "); #ifdef WEBADMIN s_string_variable("User"); s_string("="); s_string_variable("bob"); s_string("; Lang="); s_string_variable("en"); s_string("; Theme=standard"); #endif #ifdef TOMCAT s_string_variable("JSESSIONID"); s_string("="); s_string_variable("B3ED5F0D71E3C6CD504705BAFD67E0"); s_string("."); s_string_variable("tomcatinstance1"); #endif s_string("\r\n"); #ifdef BASIC_AUTH s_string("Authorization: "); s_string_variable("Basic"); s_string(" "); s_string_variable("QWxhZGRpbjpvcGVuIHNlc2FtZQ"); s_string("==\r\n"); #endif s_string("User-Agent: "); s_string_variable("Mozilla/4.76 [en] (X11; U; Linux 2.4.2-2 i686)"); s_string("\r\n"); s_string_variable("Variable"); s_string(": "); s_string_variable("result"); s_string("\r\n"); s_string_variable(""); s_string("Host: "); s_string_variable("localhost"); s_string("\r\n"); #endif #ifdef BODY s_string("Content-length: "); s_string_variable(""); s_blocksize_unsigned_string_variable("post",7); s_string("\r\n"); #endif #ifdef RTSP s_string("Accept: application/sdp"); #else s_string("Accept: "); s_string_variable("image/"); s_string_variable("gif"); s_string(", image/x-xbitmap, image/jpeg, image/pjpeg, image/png"); #endif s_string("\r\n"); #ifdef RTSP #ifdef RTSP_DESCRIBE s_string("Bandwidth: "); s_string_variable("393216"); s_string("\r\n"); s_string("ClientID: "); s_string_variable("WinNT_5.1_6.0.11.868_RealPlayer_RN10PD_e-us_UNK"); s_string("\r\n"); s_string("RegionData: "); s_string_variable("10034"); s_string("\r\n"); s_string("Require: "); s_string_variable("com.real.retain-entity-for-setup"); s_string("\r\n"); s_string("SupportsMaximumASMBandwidth: "); s_string_variable("1"); s_string("\r\n"); s_string("ClientChallenge: "); s_string_variable("deee2996aca6c64db4ff59e0e3fb386f"); s_string("\r\n"); s_string("CompanyID: "); s_string_variable("nB9UbGcLzuKoS++5MTGHIg"); s_string("==\r\n"); s_string("GUID: "); s_string_variable("00000000-0000-0000-0000-000000000000"); s_string("\r\n"); s_string("Pragma: "); s_string_variable("initiate-session"); s_string("\r\n"); #endif #endif #ifndef RTSP s_string("Accept-Encoding: "); s_string_variable("gzip"); s_string("\r\n"); s_string("Accept-Language: "); s_string_variable("en"); s_string("\r\n"); s_string("Accept-Charset: "); s_string_variable("iso-8859-1,*,utf-8"); s_string("\r\n"); #endif s_string("\r\n"); /*Done with Headers*/ s_block_start("post"); /*begin POST block*/ s_setfirstvariable(); #ifdef BODY s_string_variables('&',"User=bob&Password=foo&languageselect=en&Theme=Heavy&Logon=Sign+In\r\n\r\n "); #endif #ifdef XML s_string("<?xml version=\"1.0\"?>\n"); s_string("<g:searchrequest xmlns:g=\"DAV:\">\n"); s_string("<g:sql>\n"); s_string("SELECT \"DAV:"); s_string_variable(""); s_string("displayname\" from scope()\n"); s_string("</g:sql"); s_string_variable(""); s_string(">\n"); s_string("</g:searchrequest>"); #endif /* s_string("username="******""); s_string_repeat("A",500); */ s_block_end("post"); /* Start webfuzzpostlude.c */ if (spike_send_tcp(target,port)==0) { /*this whole block is a bit wrong. Really we need to exit or something.*/ printf("Couldn't connect to host or send data!\r\n"); spike_close_tcp(); if (fuzzstrnum==s_get_max_fuzzstring()) { break; } fuzzstrnum++; s_incrementfuzzstring(); //sleep(5); continue; } /*see, the thing is that the spike is not guaranteed to be null terminated, so just a plain printf on the s_get_databuf() is ill-advised.*/ memset(requestbuffer,0x00,sizeof(requestbuffer)); if (s_get_size()>2500) memcpy(requestbuffer,s_get_databuf(),2500); else { memcpy(requestbuffer,s_get_databuf(),s_get_size()); } /*here we print out our request*/ printf("Request:\n%.2500s\nEndRequest\n",requestbuffer); first=1; notfin=1; retval=1; printf("Response:\n"); while(retval && notfin) { memset(buffer,0x00,sizeof(buffer)); notfin=s_fd_wait(); notfin=s_fd_wait(); notfin=s_fd_wait(); if (!notfin) { printf("Server didn't answer in time limit\n"); break; } retval=read(our_spike->fd,buffer,2500); if (first && (retval==-1 || retval==0) ) { printf("***Server closed connection!\n"); fprintf(stderr,"Request: %s\n",requestbuffer); fprintf(stderr,"***Server closed connection!\n"); break; } first=0; if (retval) { if (strstr(buffer, "500 ok") || strstr(buffer,"Internal Server Error") ) { fprintf(stderr,"Request: %s\n",requestbuffer); fprintf(stderr,"Response: %s\n",buffer); } printf("**%.500s**\n",buffer); /*this is where you filter responses out that you don't want to bother seeing.*/ #if 0 /*don't print out 404 errors*/ if (!strstr(buffer,"404") && !strstr(buffer,"400 Bad Request") && !strstr(buffer,"check that it is entered correctly")) break; #endif /*here we speed things up by no continuing to read past this dumb error message*/ /*do this same thing for any request that continues to slow you down and is non-interesting*/ if (strstr(buffer,"<TITLE>404")) break; if (strstr(buffer,"<TITLE>401")) break; if (strstr(buffer,"401 Access denied")) break; if (strstr(buffer,"Public: OPTIONS")) break; if (strstr(buffer,"Please do not alter this file")) break; if (strstr(buffer,"GIF89a")) break; if (strstr(buffer,"This object may be found <a HREF=\"localstart.asp\"")) break; if (strstr(buffer,"home page, and then look for links to the information you want")) break; if(strstr(buffer,"Location: localstart.asp")) break; if (strstr(buffer,"This is the default page that appears on new AOLserver installations")) break; if (strstr(buffer,"This page intentionally left blank.")) break; } }/*end while read loop*/ printf("End response\n"); fuzzstrnum++; s_incrementfuzzstring(); spike_close_tcp(); /*Use this for testing against netcat*/ /* sleep(1); */ }/*end for each fuzz string*/ fuzzvarnum++; s_incrementfuzzvariable(); }/*end for each variable*/ printf("Done.\n"); return 0; } /*end program*/