再提供一種解決Nginx文件類型錯誤解析漏洞的方法
昨日,80Sec 爆出Nginx具有嚴重的0day漏洞,詳見《Nginx文件類型 錯誤解析漏洞》。只要用戶擁有上傳圖片權限的Nginx+PHP服務器,就有被入侵的可能。
其實此漏洞并不是Nginx的漏 洞,而是PHP PATH_INFO的漏洞,詳見:http://bugs.php.net/bug.php?id=50852&edit=1
例如用戶上傳了一張照片,訪問地址為http://www.domain.com/images/test.jpg,而test.jpg文件內的內 容實際上是PHP代碼時,通過http://www.domain.com/images/test.jpg/abc.php就能夠執行該文 件內的PHP代碼。
網上提供的臨時解決方法有:
方法①、修改php.ini,設置 cgi.fix_pathinfo = 0;然后重啟php-cgi。此修改會影響到使用PATH_INFO偽靜態的應用,例如我以前博文的URL:http://blog.s135.com/read.php/348.htm 就不能訪問了。
方法②、在nginx的配置文件添加如下內容后重啟:if ( $fastcgi_script_name ~ \..*\/.*php ) {return 403;}。該匹配同樣會一并干掉類似“/read.php/348.htm”的URI。
方法③、對于存儲圖片的location{...},或虛擬主機server{...},只允許純靜態訪問,不配置PHP訪問。例如在金山逍遙網論壇、 SNS上傳的圖片、附件,會傳送到專門的圖片、附件存儲服務器集群上(pic.xoyo.com),這組服務器提供純靜態服務,無任何動態PHP配置。各 大網站幾乎全部進行了圖片服務器分離,因此Nginx的此次漏洞對大型網站影響不大。
本人再提供一種修改 nginx.conf配置文件的臨時解決方法,兼容“http://blog.s135.com/demo/0day/phpinfo.php/test” 的PATH_INFO偽靜態,拒絕“http://blog.s135.com/demo/0day/phpinfo.jpg/test.php” 的漏洞攻擊:
{
if ($request_filename ~* .*\.php$) {
set $is_path_info '0';
}
if (-e $request_filename) {
set $is_path_info '1';
}
if ($is_path_info ~ '0') {
return 403;
}
fastcgi_pass??127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
也可將以下內容寫在 fcgi.conf文件中,便于多個虛擬主機引用:
set $is_path_info '0';
}
if (-e $request_filename) {
set $is_path_info '1';
}
if ($is_path_info ~ '0') {
return 403;
}
fastcgi_param??GATEWAY_INTERFACE??CGI/1.1;
fastcgi_param??SERVER_SOFTWARE????nginx;
fastcgi_param??QUERY_STRING?????? $query_string;
fastcgi_param??REQUEST_METHOD???? $request_method;
fastcgi_param??CONTENT_TYPE?????? $content_type;
fastcgi_param??CONTENT_LENGTH???? $content_length;
fastcgi_param??SCRIPT_FILENAME????$document_root$fastcgi_script_name;
fastcgi_param??SCRIPT_NAME????????$uri;
fastcgi_param??REQUEST_URI????????$request_uri;
fastcgi_param??DOCUMENT_URI?????? $document_uri;
fastcgi_param??DOCUMENT_ROOT??????$document_root;
fastcgi_param??SERVER_PROTOCOL????$server_protocol;
fastcgi_param??REMOTE_ADDR????????$remote_addr;
fastcgi_param??REMOTE_PORT????????$remote_port;
fastcgi_param??SERVER_ADDR????????$server_addr;
fastcgi_param??SERVER_PORT????????$server_port;
fastcgi_param??SERVER_NAME????????$server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param??REDIRECT_STATUS????200;











事實上這種修補并不完整。利用配置正則匹配的方式去限制他,而不是從根本上解決,完全可以被繞過規則。