PHP CGI、FastCGI、FPM与FPM未授权访问

得好好理一理这些都是什么东西了……

在整个网站架构中,Web Server只是内容的分发者,当访问静态文件,例如.html文件时,Web Server会去文件系统中找到这个文件,发送给浏览器;

当访问动态文件,例如.php时,Web Server根据配置知道这个不是静态文件,需要去找php解析器来处理

Module

apache中存在Module加载方式,这种方式的本质是把php作为apache的一个子模块来运行;当通过web访问php文件时,apache就会调用module来解析php代码

CGI

CGI,Common Gatewag interface,即通用网关接口;是Web Server与Web Application之间数据交换的一种协议;

CGI方式在遇到连接请求先要创建CGI的子进程,激活一个CGI进程,然后处理请求,处理完后结束这个子进程

请求流程为:

客户端 -》服务器 -》CGI -》应用程序(php) -》CGI -》服务器 -》客户端

使用CGI时,每一个web请求都必须解析php.ini、载入全部扩展并初始化全部数据结构,这是CGI性能底下的主要原因(反复加载)

FastCGI

FastCGI:是用来提高CGI性能的一种协议

Web Server启动时载入FastCGI进程管理器,FastCGI进程管理器自身初始化,启动多个CGI解释器进程,并等待来自Web Server的连接

使用FastCGI,解析php.ini、载入全部扩展并初始化全部数据结构这些工作只在进程启动时发生一次;当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器;Web Server将CGI环境变量和标准输入发送到FastCGI子进程php-cig

PHP-CGI

是php对Web Server提供的CGI协议的接口程序

PHP-FPM

FPM,FastCGI Process Manager,是FastCGI协议解析器,FPM按照FastCGI协议将TCP流解析成真正的数据;PHP-FPM是php对于Web Server提供的FastCGI协议的接口程序

php5.3版本之后,PHP-FPM是内置于PHP的;PHP-FPM通过生成新的子进程可以实现php.ini修改后的平滑重启

php到底用的上面哪种类型的接口程序,可直接在phpinfo的Server API中找到

PHP-FPM未授权访问

先上ph大神文章链接:https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html;按照思路自己理解理解。。。

1.PHP-FPM解析FastCGI数据包后,会根据得到的环境变量,执行SCRIPT_FILENAME项所指向的PHP文件;后来FPM配置中新增了一个选项security.limit_extensions,其限定了只有某些后缀的文件才允许被FPM执行,默认为.php

2.PHP.INI的两个配置项:

  • auto_prepend_file:告诉PHP在执行目标文件之前,先包含此配置所指定的文件
  • auto_append_file:告诉PHP在执行完目标文件后,包含此配置所指定的文件

3.PHP-FPM的两个环境变量(可以用来设置PHP配置项):

  • PHP_VALUE:可以设置模式为PHP_INI_USER
  • PHP_ADMIN_VALUE:可以设置所有选项(除disable_functions,该选项是PHP加载的时候就确定了)

4.根据上述知识点,利用PHP-FPM执行任意代码:

(1)PHP-FPM端口(默认9000)暴露在公网(SSRF)
(2)找到一个已存在的PHP文件的绝对路径,如/usr/local/lib/php/PEAR.php
(3)使用PHP_ADMIN_VALUE设置auto_prepend_file=php://inputallow_url_include=On
(4)将需要执行的代码POST到指定的PHP文件中


测试如下:

1.首先配置PHP-FPM监听端口:

cd /etc/php/7.0/fpm/pool.d
vi www.conf

设置:listen=0.0.0.0:9000(以前默认是/run/php/php7.0-fpm.sock)

之后重启FPM:systemctl restart php7.0-fpm.service

2.其次配置nginx:

location ~ \.php$ {
       include snippets/fastcgi-php.conf;
       fastcgi_pass 0.0.0.0:9000;

之后重启nginx,开放阿里端口

3.clone p牛编好的exp,修改后运行:

python3 php-fpm.py  101.132.41.135 /var/www/index.php -c '<?php  echo `ls`; ?>'

即可看到代码执行的结果


参考链接:

https://segmentfault.com/a/1190000008627499

https://www.php.cn/php-weizijiaocheng-392861.html