nginx文件類型錯誤解析漏洞

漏洞介紹:Nginx ("engine x") 是一個高性能的 HTTP和反向代理服務器,Nginx作爲WEB服務器可以處理靜態文件,索引文件以及自動索引,能夠使用緩存加速反向代理,並提供簡單的負載均衡及容錯、模塊化的架構等功能。

PHP CGI 中 fix_pathinfo 引起的解析漏洞分析

這個安全問題最早被人所瞭解是通過國內安全組織80sec的一篇文章《nginx文件類型錯誤解析漏洞》,文章指出當Nginx配置FastCGI使用PHP時,會將諸如http://www.test.com/test.jpg/anything.php 這樣的請求,把test.jpg當作PHP文件來進行解析,而anything.php這個文件並不存在。實際上這並不是一個Nginx的漏洞,而是PHP5默認配置的缺陷造成的。

示例:


問題的本質是什麼呢?
比如, 下面的Nginx conf(Nginx配置文件):

location ~ \.php($|/) {
     fastcgi_pass   127.0.0.1:9000;
     fastcgi_index  index.php;
     set $script    $uri;
     set $path_info "";
     if ($uri ~ "^(.+\.php)(/.*)") {
          set  $script     $1;
          set  $path_info  $2;
     }
     include       fastcgi_params;
     fastcgi_param SCRIPT_FILENAME   $document_root$script;
     fastcgi_param SCRIPT_NAME       $script;
     fastcgi_param PATH_INFO         $path_info;
}
當我們發出http://www.test.com/test.jpg/anything.php這樣的請求時,通過“^(.+\.php)(/.*)”這段正則匹配後,SCRIPT_NAME會被設置爲“test.jpg/anything.php”,繼而構造成SCRIPT_FILENAME傳遞給整個PHP CGI,但是PHP又爲什麼會接受這樣的參數,並且把test.jpg解析了呢?問題就在於PHP的CGI SAPI中的參數cgi.fix_pathinfo這個參數了。
關於cgi.fix_pathinfo這個參數的描述:
; 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 it's 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.
cgi.fix_pathinfo=1
      上述描述了默認情況cgi.fix_pathinfo的值爲1,那麼如果開啓了這個選項,就會觸發在PHP中的如下邏輯:
/*
 * if the file doesn't exist, try to extract PATH_INFO out
 * of it by stat'ing back through the '/'
 * this fixes url's like /info.php/test
 */
if (script_path_translated &&
     (script_path_translated_len = strlen(script_path_translated)) > 0 &&
     (script_path_translated[script_path_translated_len-1] == '/' ||
....//以下省略

PHP CGI 以 / 爲分隔符號從後向前依次檢查路徑,當檢測到test.jpg/anything.php時,PHP會認爲SCRIPT_FILENAME是test.jpg, 而anything.php是PATH_INFO, 然後PHP就把test.jpg當作一個PHP文件來解釋執行。

在很多使用 php-fpm (<0.6) 的主機中也會出現這個問題,但新的 php-fpm 的已經關閉了 cgi.fix_pathinfo。

提示:可使用copy命令製作圖片木馬,如copy a.jpg/b+a.txt/a b.gif

本文摘自:合天網安實驗室

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章