web

[BJDCTF2020]Mark loves cat

noob
2020-10-21 / 0 评论 / 150 阅读 / 正在检测是否收录...

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

2

评论 (0)

取消