无参数读文件(RCE)

学习学习

Posted by lll-yz on April 20, 2021

原文来自—>here

什么是无参数

顾名思义,就是只使用函数,且函数不能带有参数,这里有种种限制:比如我们选择的函数必须能接受其括号内函数的返回值,使用的函数规定必须参数为空或者为一个参数等。

例题讲解

例题:

<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);
}
?>

代码解析:

preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])

这里使用preg_replace替换匹配到的字符为空,\w匹配字母、数字和下划线,等价于[^A-Za-z0-9],然后(?R)?这个意思为递归整个匹配模式。

举个例子:

a(b(c()));可以使用,但是a(‘b’)或a(‘b’, ‘c’)的这种含有参数的都不能使用。

所以我们要使用无参数的函数进行文件读取或者命令执行。

无参数任意文件读取

查看当前目录文件名

正常的,print_r(scandir('.'));可以用来查看当前目录所有文件名。

cLs8N8.md.png

但是要怎么构造参数里这个点呢,这里介绍几个方法:

  • localeconv()

    localeconv()返回一包含本地数字及货币格式信息的数组。而数组第一项就是.

cLs7CD.png

要怎么取到这个点呢,这里就要用到另一个函数:

current()返回数组中的单元,默认取第一个值:

cLyKGF.md.png

print_r(scandir(current(localeconv())));成功打印出当前目录下的文件。也可以使用 print_r(scandir(pos(localeconv())));poc是current的别名。

如果都被过滤了还可以使用reset(),该函数返回数组第一个单元的值,如果数组为空则返回FALSE。

  • chr(64)

    chr(64)就是字符.

    要构造46,有几个方法:

    chr(rand())		#不切实际,看运气
    chr(time())
    chr(current(localtime(time())))
    

    chr(time()):

    chr()函数以256为一个周期,所以chr(46), chr(302), chr(558)都等于.,所以使用chr(time()),一个周期必定会出现一次.

    chr(current(localtime(time()))):

    数组第一个值每秒+1,所以最多60秒就一定能得到46,用current(pos)就能获得.

……