Nginx+PHP 配置漏洞:静态文件都可以当作 PHP 解析

漏洞危险等级:毁灭性。
这个漏洞严格上说并不是 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,这样静态文件就永远不能被解析了。
补充方案:
if (!-e $request_filename) {
        rewrite .*   http://www.iaibi.com/index.php;
        }
临时解决方案 以上有重写的同学 慎用
if ( $fastcgi_script_name ~ \..*\/.*php ) {
        return 403;
        }
通杀,限制PHP引擎仅能处理.php的文件
注:设置php.ini的cgi.fix_pathinfo为0,重启php。最方便,但修改设置的可能对你网站有影响!是比较鲁莽的做法!
补充方案缺点:
已经可以实现防止漏洞的效果,但是如果你的网站是康盛的程序或者其他开源程序需要开启rewrite伪静态的程序,那么就会出现rewrite伪静态后的静态页面不能访问!(线上生产环境试验)
个人解决方法(在补充方案的基础上修改):
if ( $fastcgi_script_name ~ \.*\.(png|jpg|gif|bmp|PNG|JPG|GIF|BMP)\/.*php ) {
           return 404;
        }

Nginx如何配置可以让.html后缀的静态文件当php动态文件执行

有两种方式修改nginx配置文件可以实现。
方式一:打开你的网站的nginx配置文件,然后找到:“location ~ \.php$ {”,再把其中的\.php修改为:“\.php|\.html”,保存后重启nginx即可。
方式二:同上,打开配置文件找到:“location ~ \.php$ {”,然后把location整段复制,在下面粘帖上,再把\.php修改为\.html,保存后重启nginx即可生效。
上述两种方式的配置示例代码如下:location ~ \.php|\.html$ {
            fastcgi_pass 127.0.0.1:9000; 
            fastcgi_index index.php; 
            fastcgi_param SCRIPT_FILENAME /webs$fastcgi_script_name; 
            include fastcgi_params; }
示例代码二(添加html重复段): location ~ \.html$ { 
            fastcgi_pass 127.0.0.1:9000; 
            fastcgi_index index.php; 
            fastcgi_param SCRIPT_FILENAME /webs$fastcgi_script_name; 
            include fastcgi_params; }

LNMP 配置漏洞系列解读相关推荐

  1. 漏洞复现-webmin漏洞系列分析与利用

    webmin漏洞系列分析与利用 Webmin 远程代码执行CVE-2022-0824 编号CVE编号:CVE-2022-0824 影响版本 漏洞简介 复现 拉取漏洞镜像 启动漏洞环境 解决方案 POC ...

  2. 经验分享 | 通过adbd配置漏洞在安卓设备上提升权限

    近日,Android上的一个本地提权漏洞已被确认,该漏洞可通过设备上运行的Android Debug Bridge Daemon(adbd)被利用. 如果一个安卓设备被发现正在运行于TCP端口监听的a ...

  3. LSI SAS3IRCU配置SAS3系列RAID卡

    LSI SAS3IRCU配置SAS3系列RAID卡 一.适用的controller LSISAS3008 LSISAS3004 二.名词解释 Controller: IR: Volume: 卷,基于物 ...

  4. 《通用数据保护条例》(GDPR)系列解读一:如何判断出海企业是否受GDPR管辖?

    2018年被称为"世界数据治理元年".在这一年的5月25日,<通用数据保护条例>(GDPR)在经过两年的缓冲期后正式步入执法阶段.作为全球首部全面的个人数据保护法,它的 ...

  5. php 静态配置文件问题,Nginx+PHP 配置漏洞:静态文件都可以当作 PHP 解析

    漏洞危险等级:毁灭性. 这个漏洞严格上说并不是 Nginx 和 PHP 本身的漏洞造成的,而是由配置造成的.在我之前写的许多配置中,都普遍存在这个漏洞. 简易检测方法: 打开 Nginx + PHP ...

  6. SOLIDWORKS中如何使用配置创建系列零件

    随着产品向模块化.标准化发展,零件的设计也向着系列化发展,他们外形很接近,只是尺寸.某些细小特征有所区别,如果逐个创建这些零件,就比较费时费力,而使用配置可以使用同一个零件创建一系列零件,设计效率大大 ...

  7. 2022-10-15(Linux应急响应、配置漏洞之DNS域传送、内网渗透之内网主机发现技巧)

    http://noahblog.360.cn/advanced-windows-taskscheduler-playbook/@[toc] [重要]拜读的文章链接都在标题上. 一.linux应急响应 ...

  8. 从梁飞的微型rpc 细节说起--Dubbo源码系列解读(5)

    7年前,梁飞公布了一个微型的rpc,这个rpc核心就是一个类,2个方法,但重点我们要探讨是细节的设计和质量一些问题 package com.rpc;import java.io.ObjectInput ...

  9. ATI MINI40配置NI系列软件

    ATI MINI40配置NI系列软件 对于NI几个套件的基本介绍 ATI MINI40的需要了解的基本内容 整体软件安装 安装前的要求 正式安装 TIPS 对于NI几个套件的基本介绍 NI(Natio ...

最新文章

  1. AtCoder AGC031D A Sequence of Permutations (群论、置换快速幂)
  2. php输出内容到页面,php实时输出内容
  3. sas 怎么连接mysql_sas连接MySQL
  4. NYOJ266 - 字符串逆序输出
  5. xftp找不到匹配的outgoing encryption 算法 怎么解决
  6. 刚刚,2020年中国信息通信技术服务大会盛大召开!
  7. hibernate还有人用吗
  8. debian 文件夹中文件大小_linux 查看文件和文件夹大小
  9. 在网易咔哒上面制作SCRATCH小程序
  10. 数字图像处理基础——图像空间操作的3种形式
  11. react 输入框 回车事件切换
  12. AU降噪 李兴兴
  13. python怎么输入括号
  14. 微信支付V3版 java
  15. 数据图像处理——期末复习知识点
  16. 线程池的七个核心参数
  17. 阿里云服务器怎么样?详细介绍
  18. 给div加滚动条 div显示滚动条设置代码
  19. 微信小程序接入微信支付流程
  20. Win7系统提示“内置管理员无法激活此应用”的原因和解决方法

热门文章

  1. 3GPP TS 29244-g30 中英文对照 | 5.4.9 Provisioning of Predefined PCC/ADC Rules
  2. 上了一堂健身课,27岁程序员尿尿像酱油!
  3. 基于xlsx-populate实现的前端埋点导出
  4. Windows Azure 解决方案系列: Real World Windows Azure: 与微软杰出工程师, Sean Nolan的访谈
  5. java 俄罗斯 id_Java ZoneId systemDefault()用法及代码示例
  6. 5G注册流程分级详解Step4-8
  7. safari 浏览器版本升级后提示“此网页出现问题,已重新载入网页” 解决办法
  8. PPT不能编辑,如何取消PPT的只读模式?
  9. 市场营销工作重中之重——提升工作效率
  10. 基于Patachmatch的stereo matching笔记(一):《PatchMatch Stereo》