代码审计--变量覆盖漏洞

可能会导致变量覆盖漏洞的函数有parse_str(),extract(),import_request_variables()以及$$。

1.parse_str()导致的漏洞

<!--
parse_str($a = $_GET['flag']);

if ($bdctf == "BCDEF") {
     echo $flag;
}
-->

源码分析:a获得一个get值$flag ,如果$bdctf == "BCDEF"输出flag。

思路:由代码知,如果想要得到flag必须先输入一个flag。看到 parse_str()想到变量覆盖,构造payloa ?flag=&bdctf=BDCTF 得到flag

parse_str()定义和用法

parse_str() 函数把查询字符串解析到变量中。

注释:如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量。

注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。

语法

parse_str(string,array)
参数 描述
string 必需。规定要解析的字符串。
array 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。

 2.extract()漏洞

<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan))
{
$content=trim(file_get_contents($flag));
if($shiyan==$content)
{
echo'flag{xxx}';
}
else
{
echo'Oh.no';
}
}
?>

源码分析: extract()  获得一个get值是shiyan。content从flag里获得一个去空的flag字符串。如果相等,输出flag。

思路:: 看到extract(),想到变量覆盖,构造payload ?shiyan=&flag= 得到flag

extract()定义和用法

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

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

第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。

该函数返回成功导入到符号表中的变量数目。

语法

extract(array,extract_rules,prefix)
参数 描述
array 必需。规定要使用的数组。
extract_rules

可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。

prefix

可选。请注意 prefix 仅在 extract_type 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。

前缀和数组键名之间会自动加上一个下划线。

3.$$漏洞

    1.<?php

    2.include “flag.php”;

    3.$_403 = “Access Denied”;

    4.$_200 = “Welcome Admin”;

    5.if ($_SERVER["REQUEST_METHOD"] != “POST”)

    6.    die(“BugsBunnyCTF is here :p…”);

    7.if ( !isset($_POST["flag"]) )

    8.    die($_403);

    9.foreach ($_GET as $key => $value)

    10.    $$key = $$value;

    11.foreach ($_POST as $key => $value)

    12.    $$key = $value;

    13.if ( $_POST["flag"] !== $flag )

    14.    die($_403);

    15.echo “This is your flag : “. $flag . “\n”;

    16.die($_200);

    17.?>

源码分析:

1、 Include 调用了flag.php文件
2、$_200,$403 定义两个参数,以及参数值。
3、接着是两个判断语句,判断访问页面的方法是否为post方法和有没有参数flag。
4、再接着两个foreach函数遍历数组函数,这里就是把我们用get方法传输的数据当做数组进行遍历,并将遍历的参数赋值给key,将参数值复制给value。
5、还有一个if判断语句,判断用post方法传输的数据是不是和$flag的值相同,如果相同,输出flag。
6、最后输出$200的内容。

解题思路:

由于第7,11-14行间的代码会将$flag的值给覆盖掉,所以只能利用第一个foreach先将$flag的值赋给$_200,然后利用die($_200)将原本的flag值打印出来。

payload:

Get方法传输:?_200=flag
Post方法传输:flag=abcde

猜你喜欢

转载自blog.csdn.net/qq_40657585/article/details/83545051