可能会导致变量覆盖漏洞的函数有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 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。 |
-
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