3

[BJDCTF2020]Mark loves cat-1|源代码泄露|变量覆盖 - upfine

 2 years ago
source link: https://www.cnblogs.com/upfine/p/16593710.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

[BJDCTF2020]Mark loves cat-1|源代码泄露|变量覆盖

主要考察了:源代码泄露、变量覆盖

共展示了三种获取flag的方式

1、打开题目查看未发现有效信息,查看源代码信息,发现返回的dog信息,结果如下:

2834847-20220816161812348-688076655.png

2834847-20220816161755499-429029465.png

2、使用dirmap进行目录扫描,发现了.git/config,那就想到了源代码泄露的问题,使用githack工具获取源代码信息,但是只获取到了一些js文件和图片,未获取到源代码信息,结果如下:

2834847-20220816162115791-1886551838.png

2834847-20220816162332251-663380376.png

3、可以看到可以是存在flag.php、index.php文件的,但是githack并未获取到,因此在网上查找了下相关的源码信息,结果如下:

index.php

<?php
    $flag = file_get_contents('/flag');
?>

index.php

<?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;

4、对源代码进行审计分析,定义了三个变量并对三个变量进行了输出,但是我们想要的是输出flag的值,这里就想到了变量覆盖的问题,源代码中存在多个变量输出的地方,应该是都可以覆盖成flag进行输出,那就从第一个开始进行分析,代码如下:

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){  //传入的变量为flag   value不是flag
        exit($handsome);
    }
}

我们想要输出flag值就需要$handsome=$flag,这样exit($handsome)才能输出exit($flag),这个条件又要求get方式传递flag值($y)需要能等于传递的参数$X并且不等于flag(这里可以确定一定不是一个参数但是可以确定一个参数是flag),加上$handsome=$flag,所以猜测$x=$handsome(那这里就确定了另外一个参数和flag参数的值),在考虑到刚刚说的:$handsome=$flag,所以这里也确定了handsome参数的值,所以最终的payload应该是:?handsome=flag&flag=handsome。

5、输出payload查看返回信息的源代码发下flag值,结果如下:

2834847-20220816164419922-269935089.png

6、那分析第二个输出的变量,代码如下:

if(!isset($_GET['flag']) && !isset($_POST['flag'])){  
    exit($yds);
}

这里要求不存在flag参数,就绕过了上面第一个输出,并且最终输出的是$yds,那我们就需要使$yds=$flag,这里传递参数后会执行下面的代码:

foreach($_GET as $x => $y){    
    $$x = $$y;  //GET型变量重新赋值为当前文件变量中以其值为键名的值
}

查看这个代码,我们最终需要的这个代码形成$yds=$flag,那就是$x=yds,$y=flag,因此这里的fpayload:?yds=flag。

7、输入payload查看返回信息的源代码发下flag值,结果如下:

2834847-20220816165840417-2033539941.png

8、那分析第三个输出的变量,代码如下:

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){   
    exit($is);
}

这里传递方式有两种get和post,不同的传参方式可能不太一样,这里就以get方式来说,这里要求我们传递flag参数并且其值也为flag,最终输出的exit($is)我们想要exit($flag),那就需要$is=$flag,这里仍会执行下面这个函数:

foreach($_GET as $x => $y){    
    $$x = $$y;  //GET型变量重新赋值为当前文件变量中以其值为键名的值
}

所以我们就需要传递两个参数:一个flag=flag,一个is=flag,所以payload:is=flag&flag=flag。

9、输入payload查看返回信息的源代码发下flag值,结果如下:

2834847-20220816170445859-324080757.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK