php 7.4+绕过disable_functions的核心是ffi扩展,它绕过php函数表直接调用libc.so.6中的system等c函数;前提为ffi.enable=true、libffi已安装、libc路径正确且可读。

PHP 7.4 及以上版本能绕过 disable_functions,核心靠的是 FFI ——它不走 PHP 函数表,而是直接调用 C 标准库,system() 这类被禁的函数根本拦不住它。
确认 FFI 是否可用
绕过前提不是“有 PHP 7.4”,而是 ffi.enable 必须开启且 libffi 库已就位。很多生产环境默认关着 ffi.enable,光看版本没用。
- 先执行
phpinfo()或var_dump(FFI::cdef(''));,若报Class 'FFI' not found或ffi.enable is disabled,说明不可用 -
php -m | grep ffi在命令行检查扩展是否加载 - 即使扩展存在,也要确认
php.ini中ffi.enable = true或ffi.enable = preload(后者需配合 opcache.preload)
用 FFI 直接调用 libc 的 system()
FFI 绕过本质是绕开 PHP 层函数黑名单,转而调用底层 libc.so.6 的 system()。不需要写扩展、不依赖 proc_open 等漏网函数,只要 libc 路径对、权限够,就能执行。
- 典型调用方式:
$ffi = FFI::cdef("int system(const char *command);", "/lib/x86_64-linux-gnu/libc.so.6"); $ffi->system("id"); - Linux 下 libc 路径可能为
/lib64/libc.so.6(CentOS)、/usr/lib/libc.so(部分 Alpine),需先ls -l /lib*/*libc*确认真实路径 - 若目标禁用了
dl()或putenv(),不影响 FFI,但若open_basedir限制了 libc 所在目录,会触发Permission denied
常见失败原因和绕过技巧
实战中不是写对代码就一定成功,几个关键卡点经常被忽略:
-
FFI::cdef()第二个参数传错路径:空字符串或相对路径会静默失败,必须是绝对路径且 Web 进程有读权限 - SELinux 或 AppArmor 启用时,即使 libc 可读,
system()调用也可能被拦截,此时strace看系统调用会显示EPERM - 某些容器环境(如极简 Alpine 镜像)没装
libc动态库,只有musl,得换libmusl对应的调用方式,或改用LD_PRELOAD方案 - 蚁剑等工具的 FFI 插件默认用
libc.so.6,若目标是 ARM64 或旧内核,可能需要手动指定/lib/aarch64-linux-gnu/libc.so.6等路径
真正难的从来不是“怎么写 FFI 调用”,而是判断当前环境里 ffi.enable 是否真开了、libc 能不能读、有没有 SELinux 拦着——这些细节一错,连错误都不报,只返回空或 false。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











