打开场景,是一个主页,先审计源码,发现很多a链接,但都是指向本页面的死链,没啥用 扫目录,python3 dirmap.py -i http://bba5d728-52ed-427c-bf70-629b758fa581.node4.buuoj.cn:81/ -lcf 扫出来一堆.git,那么就考虑git源码泄露 githacker --url http://bba5d728-52ed-427c-bf70-629b758fa581.node4.buuoj.cn:81/.git --folder result1 查看结果,一目录,两文件,最重要的是index.php 把重要的部分截出来
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
分析一下逻辑,发现很明显最后的echo"the flag is".$flag 是一定执行不到的 具体原因
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
因此不管是get还是post,你必须带一个flag参数过去 但是你一旦带了flag参数,假设是get过去的,假设?flag=aaa,就会触发
foreach($_GET as $x => $y){
$$x = $$y;
}
flag=aaa $flag=$aaa,$flag被覆盖为空,你不管传什么,flag都会被覆盖成你自定义的变量,唯一能绕过的方法就是flag=flag或者flag=aaa&aaa=flag
但是带过去的flag参数不能是flag因为
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
即$flag=$flag就别想了,
那么flag=aaa&aaa=flag呢,也过不去,因为
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
即flag参数的值不能是其他请求参数,防止你通过中间变量构造$flag=$flag
真坏啊!!!!!!!!!
那么靠get这条路去echo "the flag is: ".$flag;就堵死了
下面来讨论post带flag参数过去
其实是同样的道理,我敢保证这题的作者绝对是逻辑怪
foreach($_POST as $x => $y){
$$x = $y;
}
flag=aaa,$flag=aaa,好嘛,这更直接,直接给flag赋值了
到这就讨论完了为什么最后的echo肯定执行不了了,但是观察页面源码的时候我们发现他的exit()也是会回东西给我们的
好了,这就是本题的绕过点 基本思路:
$handsome=$flag
$is=$flag
$yds=$flag
这三条必须出现一条不过分吧 神奇的payload1:yds=flag
过第一层:$yds=$flag
在这里结束
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
相当于exit($flag),查看源码,拿到flag
又神奇了的payload2: is=flag&flag=flag
过第一层:
$is=$flag
$flag=$flag
很明显他在利用
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
出发后也相当于exit($is)
到这思路彻底打开了,收不住了
神奇的payload3:
/?a=flag&flag=a&handsome=flag
过第一层:
$a=$flag
$flag=$a
$handsome=$flag
然后在这停顿:
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
这里是纯靠get参数来实现的,下面来讨论post为什么不行,是因为post只有赋值功能,我们要利用exit来输出的话,必须要做的一件事是
变
量
名
=
变量名=
变量名=flag,然后触发相应的条件 利用yds的话,必须有的一件事是yds=flag,post这里flag绝对不能给值,给其他值也没意义,虽然也输出flag但是是多此一举 利用is的话,$flag=flag,而且是第一步执行,想都不要想 利用handsome的话,跟第一种情况其实是一样的,所以也没意思 参考视频链接:https://www.bilibili.com/video/BV1ML4y1p7EK/
|