1.拿到题目,没有思路,于是拿dirsearch扫描目录,发现有.git目录,于是使用GitHack拿到网站源码
2.关键代码:
`<?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;`
3.分析代码,包含flag.php,看到$$x=$$y可知是变量覆盖漏洞,然后需要了解下有关于$$的变量覆盖漏洞。
$$是可变变量,一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。$$导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值,因此就产生了变量覆盖漏洞。就这道题来说
foreach($_POST as $x => $y){
$$x = $y;
}
传入POST参数:$flag=flag,这里就相当于已经将原句变为$$flag=flag,然后再看第二步的foreach()函数
foreach($_GET as $x => $y){
$$x = $$y;
}
此时传入GET参数?yds=flag,意思就是$yds=$flag,而$flag就是真正的flag。然后看第三个foreach()函数
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
这里就是两个判断,第一个为$flag是否等于$x,第二个为$x是否不等于flag,如果正确返回$handsome,所以构造payload:
GET:?yds=flag
POST:$flag=flag
然后在源码中拿到flag。
引用:https://www.mi1k7ea.com/2019/06/20/PHP%E5%8F%98%E9%87%8F%E8%A6%86%E7%9B%96%E6%BC%8F%E6%B4%9E/
https://www.jianshu.com/p/a4d782e91852
评论 (0)