遇到一道不错的变量覆盖题,特此记录
<?php
$flag = file_get_contents('/flag');
<?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 $flag
试着get传参?flag=ddd经过第二个foreach后 $flag = $ddd,但是由于 $ddd没有赋初值为null,所以 $flag也为空,此法不通。
接着审计代码,我们注意到exit()函数
exit()函数特性:
exit() 函数退出脚本的同时输出消息
因此考虑存在exit()的三个if语句,这里有两条if语句可以实现绕过
第二条if语句:
我们通过变量覆盖达到 $ yds= $flag的效果,GET传参?yds=flag,
在第二个foreach语句中,首先是 $x=yds, $y=flag,经过 $ $x >= $ $y也就变成了 $yds= $flag
第三条if语句:
输出变量 $ is,判断条件为 $ _POST[‘flag’] === ‘flag’ || $ _GET[‘flag’] === ‘flag’,这里可以通过满足后面这个条件进行变量覆盖:GET传参?is=flag&flag=flag;在第二个foreach语句中,首先是$ x=is,$y=flag,带进去就变成了 $is= $flag,这就达到了覆盖的目的,而参数中flag=flag只是为了满足if语句;