深入浅出带你学习无参RCE


theme: geek-black

本文正在参加「金石计划 . 瓜分6万现金大奖」

前言

无参RCE,顾名思义就是当我们不能传入参数的情况下进行命令执行,因为一般情况下命令执行必须是要含有参数的,本文会就着无参RCE问题带大家学习CTF中常见的无参RCE方式及用法,下面我们展开文章来讲解一下。

基础知识

首先我们要了解,什么时候才会考虑无参RCE这种方法,我们先看下面的代码:

<?php
if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp']){
      eval($_GET['exp']);
}
?>

简单分析一下代码里面的含义,首先让我们通过GET方式传入exp,之后会进行匹配,若我们传入的值带(),那么会被替换成空,同时正则表达式是递归调用的,我们传入的值会随着匹配次数慢慢变短。

了解了以上知识,我们来学习一下如何绕过吧。

getallheaders()

这个函数根据菜鸟教程里的解释可以理解为包含当前请求所有头信息的数组,当我们传入这个函数后,可以查看回显:

图片.png

可以看到我们header头信息确实一数组的形式打印出来了,但是数组我们是不能用的,所以要想办法找到可以转换数组的函数,这里也有好几种方法,这里就简单说一下:

impload

该函数将一维数组的值转换成连续的字符串,这里我们就有思路了,因为上面函数是转换报文头为数组,而这个则是讲数组转换成字符串,这不就完美绕过了,只需在报文最后加上恶意代码即可。

图片.png

end

该函数作用是取出数组的最后一位,以字符串形式返回,可以想到,我们也可以利用这个函数,我们可以用输出函数里包裹这个,只需放在保温最前面或者最后面即可。

图片.png

get_defined_vars()

根据菜鸟教程里的解释,该函数也是返回所有一定义变量的数组,需要注意的是返回的是一个二维数组,那么我们上面的方法就不能用了,下面介绍一个新的函数current(),该函数可以返回数组中的单元且初始指针指向数组的第一个单元,正好是GET方式传入的第一个元素我们就可以用这个函数先转换成一维数组,在进行POC的构造:

?exp=eval(end(current(get_defined_vars())));&shell=phpinfo();

session_id()

这个方法就跟上面的不太一样了,我们需要将恶意代码卸载cookie的phpsession里,然后通过这个来进行读取,可能有一些抽象,一会会进行演示

图片.png

我们要先知道必须得先开启session才可以使用该方法,我们常用的payload如下:

hex2bin(session_id(session_start()));

因为session里面的值不能直接传入,这里要加一步16禁止编码才行得通:

于是我们最终的payload如下:

?exp=eval(hex2bin(session_id(session_start())));

图片.png

其中hex2bin为16进制解码的函数,因为我们之前进行了一次16进制的编码,这里不要忘记了。

例题

题目源码如下:

图片.png

可以大体的看到分为三关,需要我们分别绕过,首先我们要知道flag文件叫什么,localeconv()函数能够返回包含本地数字及货币格式信息的数组,该数组的第一个元素就是’ . ‘,我们需要通过

scandir('.')

来查看当前目录文件,既然localeconv函数可以返回数组且第一个元素为我们想要的,所以结合前面知识构造:

?exp=var_dump(scandir(current(localeconv())));

得知flag在flag.php里,接下来考虑如何构造,因为数组索引为3,这里考虑通过next函数配合array_reverses来讲数组倒序,配合高亮函数来进行解题:

?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

最终得到flag。

结语

本文带大家学习了无参RCE的基本利用函数以及利用方法,当然远远不止这些,可以说生活中你常用的函数都有可能去构造无参RCE,有兴趣的小伙伴可以去了解更多的解法,喜欢本文的希望可以一键三连支持一下。

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容