如果我们程序写得不严谨,就会出现变量覆盖漏洞,这在PHP代码审计里也是很常见的,下面给大家分享一下哪些情况下就可以造成PHP变量覆盖漏洞?
1、extract()
extract— 从数组中将变量导入到当前的符号表。该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
<?php
/* 假定 $var_array 是 wddx_deserialize 返回的数组*/
$size = "large";
$var_array = array("color" => "blue",
"size" => "medium",
"shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");
echo "$color, $size, $shape, $wddx_size\n";
?>
以上例程会输出:
blue, large, sphere, medium
2、parse_str()
parse_str — 将字符串解析成多个变量,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。
<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
// 推荐用法
parse_str($str, $output);
echo $output['first']; // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz
// 不建议这么用
parse_str($str);
echo $first; // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz
?>
3、import_request_variables()
(PHP4 >=4.1.0,PHP5<5.4.0)
import_request_variables:将GET/POST/Cookie变量导入到全局作用域中。
曾经存在的问题,现在已经不存在了,毕竟现在很多网站都在用高版本的PHP7了,低版本还是存在这个问题的。
<?php
import_request_variables("g", "get_");
echo $get_id;
?>
//提交:?id=111
//结构:111
4、遍历初始化变量($$声明变量)
由于PHP中可以使用$$声明变量,因此在遍历数组时可能会覆盖原来的值。
使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?id=1 会将$id的值覆盖,$id=1。
<?php
foreach (array('_COOKIE','_POST','_GET') as $_request)
{
foreach ($$_request as $_key=>$_value)
{
$$_key= $_value;
}
}
$id = isset($id) ? $id : 2;
if($id == 1) {
echo "flag{xxxxxxxxxx}";
die();
}
echo $id;
?>
5、全局变量覆盖
register_globals的意思就是注册为全局变量,所以当php.ini配置文件中register_globals为On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。
注意:本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
这里就不多说了,毕竟已经移除了,只是给大家提醒一下曾经有这个东西而已!