NGINX 文件類型解釋漏洞整理

nginx文件類型錯誤解析漏洞

www.xxx.com/1.jpg

內容爲PHP 代碼,如
<?php
phpinfo();
?>

後面加任意 .php
www.xxx.com/1.jpg/xxx.php
致使代碼被執行

php.ini
cgi.fix_pathinfo=1
PHP_INI_ALL 從 PHP 4.3.0 起可用 請注意:默認爲1

二者訪問時的區別
www.xxx.com/1.jpg

HTTP/1.1 200 OK
Server: nginx/版本
Date: XXX
Content-Type: text/plain
Content-Length: XX
Last-Modified: XX
Connection: keep-alive
Keep-Alive: timeout=20
Accept-Ranges: bytes

www.xxx.com/1.jpg/xxx.php
HTTP/1.1 200 OK
Server: nginx/版本
Date: XXX
Content-Type: text/html
Content-Length: XX
Last-Modified: XX
Connection: keep-alive
Keep-Alive: timeout=20
Accept-Ranges: bytes

就在Content-Type: text/plain與Content-Type: text/html


若是 jpg 是普通文件,內容直接顯示,但如內容是php代碼就杯具了,代碼直接執行
即便是最普通的配置
location ~ \.php$ {
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    include       fastcgi_params;
    fastcgi_param SCRIPT_FILENAME   $document_root$fastcgi_script_name;
}

漏洞一樣會出現,實際和 nginx關係,nginx 只是個 Proxy,只負責根據用戶的配置文件,經過 fastcgi_param 指令將參數忠實地傳遞給 FastCGI Server,問題在於 FastCGI Server 如何處理 nginx 提供的參數


http://xx.com/foo.jpg/a.php/b.php/c.php
nginx 傳遞給 FastCGI 的 SCRIPT_FILENAME 的值爲:
/foo.jpg/a.php/b.php/c.php
也就是 $_SERVER['ORIG_SCRIPT_FILENAME']

php.ini 中 cgi.fix_pathinfo = 1 時,PHP CGI 以 / 爲分隔符號從後向前依次檢查以下路徑:

/foo.jpg/a.php/b.php/c.php
/foo.jpg/a.php/b.php
/foo.jpg/a.php
/foo.jpg
直到找個某個存在的文件,若是這個文件是個非法的文件,悲劇


PHP 會把這個文件當成 cgi 腳本執行,並賦值路徑給 CGI 環境變量——SCRIPT_FILENAME,也就是 $_SERVER['SCRIPT_FILENAME'] 的值


解決辦法
1,上傳時代碼判斷文件類型
2,  nginx 解析
if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}

http://www.54chen.com/php-tech/nginx-php-cgi-of-security-hole.html
http://www.st0p.org/blog/tag/cgi-fix_pathinfo
相關文章
相關標籤/搜索