国内顶级安全团队80sec于5.20日下午6点发布了一个关于nginx的漏洞通告,因为该漏洞的存在,使用nginx+php组建的网站只要允 许上传图片就可能被黑客入侵,直到5.21日凌晨,nginx还没有发布补丁修复该漏洞。
根据Netcraft的统计,直到2010年4月,全球一共有1300万台服务器运行着nginx程序;很是保守的估计,其中至少有600万台服务 器运行着nginx并启用了php支持;继续保守的估计,其中有1/6,也就是100万台服务器容许用户上传图片
因为nginx有漏洞,这100万台服务器可能经过上传图片的方法被黑客轻易的植入木马。植入木马的过程也很是简单,就是把木马改 成图片上传就是了,因为危害很是大,就不说细节了。有兴趣的请访问 http://www.80sec.com/nginx-securit.html
说了那么多,我想你们对80sec这个顶级安全团队比较好奇吧,素包子简单介绍一下。
80sec团队由一群年轻、充满活力、充满体力、充满激情、富有创造力的未婚dota男组成,他们均在各大互联网公司从事信息安全工做,他们的口号 是know it then hack it,素包子很是认同这个观点:“咱们只要很是熟悉一个事物,就有可能客观的发现它的不足之处,同时咱们也能的发现该事物的优势”。
80sec的意思是“80端口的安全”,也就是“web安全”;同时因为该团队成员都是80后的年轻人,咱们也能够理解为“80后安全”;另外因为 sec的发音是se ke,咱们还能够理解为“80后色客”、“80后摄客”或“80后S客”,咱们对80sec的理解仅受限于想象力。
下面介绍一下他们的丰功伟绩,他们曾发现IIS、IE、FireFox、Maxthon、世界之窗、PHPWind、DeDeCMS、QQ mail、QuarkMail、EXTMail等软件的漏洞,可见硕果累累。
既然介绍了80sec,就不得不介绍另一个很是专一WEB安全的顶级安全团队80vul,该团队一样也是由80后的男童鞋组成(90后表示压力很 大:p),他们也发现了大量WEB APP的安全漏洞,例如IE、Gmail、wordpress、PHPWind、DISCUZ、MYBB等。
看到这里,想必你们内心都有那么点遗憾,那就是为什么没有80后女黑客(我不歧视伪娘,但我必须说明不是伪娘),我也有相同的遗憾。
最后发一个小道消息,听说黑客已经在行动了;安全人员、系统管理人员、行动起来吧,赶忙修复该漏洞;最好不要有侥幸心理,不然下一个被黑客入侵的可 能就是你的网站。根据80sec安全公告的描述,临时修复方法以下,可3选其一。
一、设置php.ini的cgi.fix_pathinfo为0,重启php。最方便,但修改设置的影响须要本身评估。
二、给nginx的vhost配置添加以下内容,重启nginx。vhost较少的状况下也很方便。
if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}
三、禁止上传目录解释PHP程序。不须要动webserver,若是vhost和服务器较多,短时间内难度急剧上升;建议在vhost和服务器较少的 状况下采用。
做者:Hily 原始连接:http://hily.me/blog/2010/05/nginx-php-configure-security-problem/
版权声明:能够转载,转载时务必以超连接形式标明文章原始出处和做者信息及版权声明
漏洞危险等级:毁灭性。
这个漏洞严格上说并非 Nginx 和 PHP 自己的漏洞形成的,而是由配置形成的。在我以前写的许多配置中,都广泛存在这个漏洞。
简易检测方法:
打开 Nginx + PHP 服务器上的任意一张图片,如:
若是在图片连接后加一串 /xxx.php (xxx为任意字符)后,如:
图片还能访问的话,说明你的配置存在漏洞。
漏洞分析:
下面经过分析一个很常见的 Nginx 配置来解释下漏洞的成因:
server {
listen 80;
server_name test.local;
access_log /work/www/logs/test.access.log main;
error_log /work/www/logs/test.error.log;
location / {
root /work/www/test;
index index.html index.htm index.php;
}
location ~ \.php$ {
root /work/www/test;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fpm.sock;
}
}
咱们在 /work/www/test/ 目录下新建一个文件 test.png,内容以下:
那么访问 时,输出为文本内容:
可是当在后面加上 /xxx.php 时,即 http://test.local/test.png/xxx.php,可怕的事情发生了:
Array
(
[HOSTNAME] =>
[PATH] => /usr/local/bin:/usr/bin:/bin
[TMP] => /tmp
[TMPDIR] => /tmp
[TEMP] => /tmp
[OSTYPE] =>
[MACHTYPE] =>
[MALLOC_CHECK_] => 2
[USER] => www
[HOME] => /home/www
[FCGI_ROLE] => RESPONDER
[SCRIPT_FILENAME] => /work/www/test/test.png
[QUERY_STRING] =>
[REQUEST_METHOD] => GET
[CONTENT_TYPE] =>
[CONTENT_LENGTH] =>
[SCRIPT_NAME] => /test.png/xxx.php
[REQUEST_URI] => /test.png/xxx.php
[DOCUMENT_URI] => /test.png/xxx.php
[DOCUMENT_ROOT] => /work/www/test
[SERVER_PROTOCOL] => HTTP/1.1
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_SOFTWARE] => nginx/0.7.62
[REMOTE_ADDR] => 192.168.1.163
[REMOTE_PORT] => 4080
[SERVER_ADDR] => 192.168.1.12
[SERVER_PORT] => 80
[SERVER_NAME] => test.local
[REDIRECT_STATUS] => 200
[HTTP_ACCEPT] => image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/QVOD, application/QVOD, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
[HTTP_ACCEPT_LANGUAGE] => zh-cn
[HTTP_ACCEPT_ENCODING] => gzip, deflate
[HTTP_USER_AGENT] => Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQPinyin 689; QQDownload 627; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2; TheWorld)
[HTTP_HOST] => test.local
[HTTP_CONNECTION] => Keep-Alive
[ORIG_SCRIPT_FILENAME] => /work/www/test/test.png/xxx.php
[PATH_TRANSLATED] => /work/www/test
[PHP_SELF] => /test.png/xxx.php
[REQUEST_TIME] => 1274125615
)
环境变量中,SCRIPT_FILENAME 是 Nginx 传过来的:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
$fastcgi_script_name 变量说明请参考:
http://wiki.nginx.org/NginxHttpFcgiModule
Nginx 传给 PHP 的值为 /work/www/test/test.png/xxx.php,即 $_SERVER 中 ORIG_SCRIPT_FILENAME 的值,可是 $_SERVER 中 SCRIPT_FILENAME 倒是 /work/www/test/test.png。
缘由是,/work/www/test/test.png/xxx.php 并不存在,对于这些不存在的路径,PHP 会检查路径中存在的文件,并将多余的部分看成 PATH_INFO。
这里,/work/www/test/test.png 被 PHP 解析为 SCRIPT_FILENAME,/xxx.php 被 PHP 解析为 PATH_INFO 后被丢弃,所以并无在 $_SERVER 中出现。
解决方法:
解决这个漏洞的方法很显然:关闭上面所述的解析便可。
这个解析能够在 PHP 的配置文件中设置,默认为开启。在这里咱们须要将它关闭:
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
;cgi.fix_pathinfo=1
cgi.fix_pathinfo=0
其中 cgi.fix_pathinfo=0 为新增的配置行,表示关闭 PHP 的自动 PATH_INFO 检测。关闭后,该配置漏洞便可消除。
更好的解决方案?
以上方案并非最完美的,若是你先前有用到 cgi.fix_pathinfo 这个特性,影响会很大,好比关闭后,个人 Blog(Wordpress)文章的 URL 目录形式就得用 rewrite 来实现了。
若是能够将 PHP 设置成只解析 .php 为扩展名的文件,那么这个问题解决起来会更合理。
不过我没找到相关的设置项,或许从此应该出如今 php-fpm 的配置文件中?
总结:
这类问题基本上是没法预料的,可是若是架构设计良好的话,即便存在这个问题,也不会影响安全性。这里给出架构上的安全建议:
* 尽量使动静内容分离,全部的静态内容存在于静态内容服务器,静态内容服务器上不解析PHP,这样静态文件就永远不能被解析了php