变量覆盖漏洞

变量覆盖漏洞

变量覆盖指的是可以用我们自定义的参数值替换程序原有的变量值,变量覆盖漏洞通常需要结合程序的其他功能来实现完整攻击。
变量覆盖漏洞大多由函数使用不当导致,经常引发变量覆盖的漏洞有:extract()函数和parse_str()
函数,import_request_variables()函数则是用在没有开启全局变量注册的时候,调用了这个函数则相当于开启了全局变量注册。另外部分应用利用$$的方式注册变量没验证已有变量导致覆盖。

挖掘经验
由于变量覆盖漏洞通常要结合应用其他功能代码来实现完整攻击,所以挖掘一个可用的变量覆盖漏洞不仅仅要考虑的是能够实现变量覆盖,还要考虑后面的代码能不能让这个漏洞利用起来。
由函数导致的变量覆盖比较好挖掘,只要搜寻参数带有变量的extract()、parse_str()函数,然后去回溯变量是否可控。关于我们说过的使用双$符号注册变量会导致变量覆盖,我们可以通过搜“$$”这个关键字去挖掘。

函数使用不当
目前变量覆盖漏洞大多数是由于函数使用不正确导致的,有extract()函数和parse_str()函数,import_request_variables()函数,最常见的函数是extract()函数,使用频率最高,导致的漏洞数量最多。

(I)extrcat函数
extract函数覆盖变量需要一定条件,它的官方功能说明为:从数组中将变量导入到当前的符号表。通俗的讲就是讲数组中的键值对注册成变量,函数结构如下:
int extract( array &$var_array [, int $extract_type=EXTR_OVERWRITE [, string $prefix = NULL]] )
测试代码如下:
变量覆盖漏洞_第1张图片
在浏览器中输入http://localhost/ex.php,测试结果如下图:
变量覆盖漏洞_第2张图片
原本变量$b的值为3,经过extract()函数对变量$a处理后,变量$b的值被成功覆盖为1了。

(II)parse_str函数
parse_str()函数的作用是解析字符串并且注册成变量,它在注册变量前不会验证当前变量是否已经存在,所以会直接覆盖掉已有变量。parse_str()函数有两个参数,函数用法如下:
void parse_str( string $str [,array &$arr ] )
其中$str是必须的,代表要解析注册成变量的字符串,形式为“a=1”,经过parse_str()函数之后会注册变量$a并且赋值为1。测试代码如下:
变量覆盖漏洞_第3张图片
在浏览器输入http://localhost/pa.php,结果如下:
变量覆盖漏洞_第4张图片

(III)import_request_variables函数
import_request_variables()函数作用是把GET、POST、COOKIE的参数注册成变量。函数用法如下:
bool import_request_variables( string $types [, string $prefix ] )
其中$type代表要注册的变量,当$type为GPC的时候,则会注册GET、POST、COOKIE参数为变量。
测试代码如下:
变量覆盖漏洞_第5张图片
在浏览器输入http://localhost/im.php?b=2,测试结果如下:
变量覆盖漏洞_第6张图片
从测试结果我们可以看到变脸$b的值1被覆盖成了2。

$$变量覆盖
我们先看一段经典的$$注册变量导致变量覆盖的代码,代码如下:
foreach(array(‘_COOKIE’,’_POST’,’_GET’) as $_request)
{
foreach($$_request as $_key=>$_value)
{
$$_key=addslashes($_value);
}
}
从代码中我们可以看出$_key为COOKIE、POST、GET中的参数,比如提交?a=1,则$key的值为a而还有一个$在a的前面,结合起来则是$a=addslashes($_value);所以这样会覆盖已有的变量$a的值。为了让大家更清楚,下面我们来看一段测试代码:
变量覆盖漏洞_第7张图片
在浏览器输入http://localhost/cs.php?a=2,结果如下:
变量覆盖漏洞_第8张图片
从执行结果可以看出我们成功把变量$a的值覆盖成了2。

漏洞防范
变量覆盖漏洞最常见的漏洞点是在做变量注册时以及在赋值给变量的时候没有验证变量是否存在。
解决方案:
1.使用原始变量:不进行变量注册;
2.验证变量存在:如果一定要进行变量注册,可以在注册变量前先判断变量是否存在。

你可能感兴趣的:(代码审计)