通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞。导致该漏洞的场景有: $$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_request_variables()使用不当,开启了全局变量注册等

详细可以看此文章: https://www.freebuf.com/column/150731.html

$$

0x1例题1

传入

1
?name=note

将覆盖原来$name的值
题目:

1
2
3
4
5
6
7
8
9
10
<?php
show_source(__FILE__);
$name='test';
foreach ($_GET as $key => $value)
$$key = $value;
var_dump($key);
var_dump($value);
var_dump($$key);
echo $name;
?>

0x2例题2
解法:

1
2
     ?_200=flag
post: flag=test

题目:
index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
include "flag.php";
$_403 = "Access Denied";
$_200 = "Welcome Admin";
if ($_SERVER["REQUEST_METHOD"] != "POST")
die("BugsBunnyCTF is here :p…");
if ( !isset($_POST["flag"]) )
die($_403);
foreach ($_GET as $key => $value)
$$key = $$value;
foreach ($_POST as $key => $value)
$$key = $value;
if ( $_POST["flag"] !== $flag )
die($_403);
echo "This is your flag : ". $flag . "\n";
die($_200);
?>

flag.php

1
$flag="this is a flag";

extract()

extract(array,extract_rules,prefix)该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。extract_rules默认的规则是EXTR_OVERWRITE 变量冲突时覆盖已有的变量。
0x1 例题1:
解法:

1
get请求: ?flag=&gift=

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan))
{
$content=trim(file_get_contents($flag));//file_get_contents()函数将整个文件读入一个字符串
if($shiyan==$content)
{
echo'flag{xxx}';
}
else
{
echo'Oh.no';
}
}
?>

parse_str()

parse_str ( string $encoded_string [, array &$result ] )
如果 encoded_string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 )
解法:

1
?id=a[0]=240610708

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
if (empty($_GET['id'])) {
show_source(__FILE__);
die();
} else {
include ('flag.php');
$a = "www.OPENCTF.com";
$id = $_GET['id'];
@parse_str($id);
if ($a[0]!='QNKCDZO' && md5($a[0])==md5('QNKCDZO')) {
echo $flag;
} else {
exit('其实很简单其实并不难!');
}
}
?>

import_request_variables()

import_request_variables() GET/POST/Cookie 变量导入到全局作用域中
解法:

1
?b=0

题目:

1
2
3
4
5
<?php
$b=1;
import_request_variables('GP');
print_r($b);
?>

全局变量覆盖

全局变量覆盖的关键是register_globals
register_globals的意思就是注册为全局变量。当register_globals=On,用户传递的值会被直接的注册为全局变量直接使用;register_globals==Off,需要到特定的数组里去得到它。也就是说为on的时候,变量可以从各个地方传来,当为off的时候,不会有问题。在php5.4已经被删除。
解法:

1
?auth=1

题目:

1
2
3
4
5
6
7
8
<?php
$auth=0;
echo "Register_globals: ".(int)ini_get("register_globals")."<br/>";

if ($auth){
echo "private!";
}
?>

参考文章:
https://www.freebuf.com/column/150731.html
extract变量覆盖:https://crayon-xin.github.io/2018/05/21/extract%E5%8F%98%E9%87%8F%E8%A6%86%E7%9B%96/

https://virtua11.github.io/2018/07/10/%E5%8F%98%E9%87%8F%E8%A6%86%E7%9B%96%E6%BC%8F%E6%B4%9E/