[BJDCTF2020]Mark loves cat
- ctf
- 2024-02-01
- 281热度
- 0评论
先是一个博客啥都没有,看不出来什么
直接dirsearch,发现.git源码泄露
使用Githack工具下载源码,我第一次是上面显示了有flag和index但是没有下载下来,然后多尝试几次就有了
看看源码
flag.php
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;
在这关我们绕过三个 if 函数 直接echo 明显不现实 所以突破点就是那三个 exit
上面我们要想绕过 需要
get中参数必须含有 $ x 同时$ x不能含有flag 存在get参数 或者 存在post参数 post参数恒等于 flag 或者 get参数恒等于 falg
可变变量:如果一个变量保存的值刚好是另外一个变量的名字,那么可以直接通过访问一个变量得到另外一个变量的值:在变量之前再多加一个 $ 符号
$a = 'b'; $b = 'bb'; echo $$a; // 输出 bb 1.找到 $a,解析结果:b 2.找到$b,解析结果 bb
可以简单理解为$$x就相当于是$($x)
因此关键就在
foreach($_POST as $x => $y){ $$x = $y ; //post 声明至当前文件 } foreach($_GET as $x => $y){ $$x = $$y; //GET型变量重新赋值为当前文件变量中以其值为键名的值 }
方法一:
覆盖$yds为$flag,执行exit
if(!isset($_GET['flag']) && !isset($_POST['flag'])){ exit($yds); }
我们只需让$yds=$flag
由于我们输入的变量是yds=flag 所以$x
=yds $y
=flag $$x
= $$y
所以 $yds=$flag
flag变量就是 我们要的东西 exit($yds)。就是echo $flag。
paylopad
?yds=flag
在页面最下面
方法二:
覆盖$is
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ exit($is); }
payload
?is=flag&flag=flag
前半段和前面的方法原理相同,让flag覆盖is 后面的flag=flag—>$flag=$flag 目的是为了符合第三个if需求
方法三:
覆盖$handsome
foreach($_GET as $x => $y){ if($_GET['flag'] === $x && $x !== 'flag'){ exit($handsome); } }
payload
?handsome=flag&flag=x&x=flag
后面的目的就是让我们传入的变量是 flag 值不是flag 进而能够exit handsome
这里的值表面是 x 但前面我们进行了变量覆盖使得 x=flag 所以在这里我们输出x的值就是flag的值