2010年5月3日星期一

WEB服务CGI接口漏洞分析(转)

转:http://www.xinfengit.com/05/n-9005.html

分析了一段时间的CGI接口,感觉各种WEB服务器对一些变量好象不是很统一,也没明白一些安全要求,所以造成一些安全上的漏洞,在此作一简要分析。因为是根据个人的一些理解分析,所以错误在所难免,还望大家批评指正。

主要问题是几个变量PATH_INFO、PATH_TRANSLATED、SCRIPT_NAME的处理不统一。下面是MSDN的关于这几个变量的说明,为了清楚,也把相关两个一起列出,另两个变量这两种WEB服务器应该说都是正确处理。

PATH_INFO Additional path information, as given by the client. This comprises the trailing part of the URL after the script name but before the query string (if any).

PATH_TRANSLATED This is the value of PATH_INFO, but with any virtual path name expanded into a directory specification.

QUERY_STRING The information which follows the ? in the URL that referenced this script.

REQUEST_METHOD The HTTP request method.

SCRIPT_NAME The name of the script program being executed.

为了方便说清楚,也好让大家有个印象,举一个具体实例,看看这几个变量到底是指的什么吧。比如有映射.php,那么请求:

“GET /test.php/aaa/bbb?cgivartest HTTP/1.1”,REQUEST_METHOD=GET;QUERY_STRING=cgivartest;这是不容质疑的,那另三个变量是什么呢?个人觉得MSDN里面的定义还比较准确,就是上面那几个定义。照那么说来应该SCRIPT_NAME=test.php,这是那个要执行(也可能是被别的程序解释执行)的程序,PATH_INFO=/aaa/bbb,“script name”之后“query string”之前,假如WEB主目录是“d:\inetpub\wwwroot”,那么PATH_TRANSLATED=d:\inetpub\wwwroot\aaa\bbb。

但实际情况是如何的呢,让我们来看看。用常用的两种WEB服务器建立两个环境,以做对比,看看这两种WEB服务器的处理。

环境:

1、win2000+apache1.3.14+php4;

2、win2000+iis5.0+php4;

具体配置我就不说了,相信大家都是配置高手,不用我在此多费口舌。

在每个WEB服务里面建立一个文件test.php,文件内容如下:

phpinfo();

?>

大家一看就知道是干什么,简单建立这么一个文件,方便我们查看一些WEB变量。

1、apache下直接用php.exe加载;

http://192.168.8.48/php/php.exe/abcde.php/aa/..%5c../test.php?cgivartest

得到:

Environment

Variable Value

SCRIPT_FILENAME d:/php4/php.exe

GATEWAY_INTERFACE CGI/1.1

SERVER_PROTOCOL HTTP/1.1

REQUEST_METHOD GET

QUERY_STRING cgivartest

REQUEST_URI /php/php.exe/abcde.php/aa/..%5c../test.php?cgivartest

SCRIPT_NAME /php/php.exe/abcde.php/aa/..\..

PATH_INFO /abcde.php/aa/../../test.php

PATH_TRANSLATED d:\program files\apache group\apache\htdocs\test.php

2、apache下用映射加载:

http://192.168.8.48/AB.PHP/AA/..%5C../test.php?cgivartest

得到:

Environment

Variable Value

SCRIPT_FILENAME d:/php4/php.exe

GATEWAY_INTERFACE CGI/1.1

SERVER_PROTOCOL HTTP/1.1

REQUEST_METHOD GET

QUERY_STRING cgivartest

REQUEST_URI /AB.PHP/AA/..%5C../test.php?cgivartest

SCRIPT_NAME /php/php.exe/AB.PHP/AA/..\..

PATH_INFO /AB.PHP/AA/../../test.php

PATH_TRANSLATED d:\program files\apache group\apache\htdocs\test.php

3、iis下cgi接口加载:

http://192.168.8.48:81/abc.php/aa/..%c1%1c../test.php?cgivartest

得到:

Environment

Variable Value

GATEWAY_INTERFACE CGI/1.1

PATH_INFO /abc.php/aa/..\../test.php

PATH_TRANSLATED d:\inetpub\wwwroot\abc.php\aa\..\..\test.php

QUERY_STRING cgivartest

REQUEST_METHOD GET

SCRIPT_NAME /abc.php

SERVER_PROTOCOL HTTP/1.1

4、iis下isapi接口加载:(映射.php4)

http://192.168.8.48:81/abc.php4/aa/..%c1%1c../test.php?cgivartest

得到:

ISAPI

Server Variable Value

PATH_INFO /abc.php4/aa/..\../test.php

PATH_TRANSLATED d:\inetpub\wwwroot\abc.php4\aa\..\..\test.php

QUERY_STRING cgivartest

REQUEST_METHOD GET

SCRIPT_NAME /abc.php4

SERVER_PROTOCOL HTTP/1.1

URL /abc.php4

大家看看,apache、iis两者都不是执行的 SCRIPT_NAME,而是执行的PATH_TRANSLATED。个人理解PATH_INFO从其名字来看只是一个路径信息,而不是一个文件。而WEB服务本身应该说带有chroot性质,所以说变量PATH_INFO应该限制rfc的“/../”,这点iis是做到了,用%5c这种rfc里面的编码要求是不行的,%c1%1c的解码是因为另一个漏洞。而apache呢,直接用%5c就可以,这显然应该说是一个漏洞。假设要执行的是PATH_TRANSLATED,那么大家试试把test.php换成别的名,比如另一种映射的名test.pl,这4种情况同样照php执行了。那意思是什么呢,就是说我可以任意以一种解释程序去执行一种影射文件,那显然与这种映射所要求的安全不符合,也就很容易导致源代码泄露漏洞。如果限制了PATH_INFO里面的“/../”,那么是不能返回上级目录,这样就不能用任意解释程序去解释一种映射文件。但想想如果这样SCRIPT_NAME、PATH_INFO、PATH_TRANSLATED几个变量是不是就有变量根本就没什么意思呢?个人理解应该是执行的是SCRIPT_NAME程序,PATH_INFO变量只是再提供给SCRIPT_NAME的一个附加的路径信息,比如用于在这路径下读取一些配置文件等。你看apache的SCRIPT_NAME变量就去掉了后面的文件名。

我们总结得到:

1、PATH_INFO应该限制rfc编码要求内的“/../”。这点apache有漏洞。这点可能导致源代码泄露,甚至导致可以访问任意文件。

2、PATH_TRANSLATED、PATH_INFO、SCRIPT_NAME不清楚,执行文件不清楚。这点apache、iis两者都有漏洞。这点很容易导致源代码泄露。实际上发现的有很漏洞与这脱离不了关系。可能过一段时间就会有IIS的泄露源代码漏洞补丁了,同样方法在apache上面也可以,虽然此漏洞根本原因不是因为这,但这为那漏洞提供了表现机会。那攻击主要是利用了这个漏洞加上windows文件操作的文件名末尾半个汉字截断处理漏洞,可以查看一些asp、php等源代码,过一段时间大家就可以看到了。

有兴趣的可以照着这实验自己做试验,看看各种环境对这些变量的处理,理解理解,很可能你自己就很容易的找到一些新漏洞呢。

没有评论: