nginx解析漏洞

國內頂級安全團隊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

相關文章
相關標籤/搜索