PHP变量覆盖漏洞详解
一、变量覆盖定义
变量覆盖指的是通过用户传入的参数值替换程序原有变量值的漏洞。这种漏洞可以导致修改关键变量的值,进而造成越权访问、写入webshell等严重危害。
二、变量覆盖的风险
- 越权访问:如Joomla未授权访问漏洞(CVE-2023-23752)
- 写入webshell
- 绕过权限检查
- 修改程序逻辑
三、变量覆盖常见场景
1. extract()函数
extract()函数将数组中的键名转换为变量名,键值作为变量值。
$a = "testname";
$my_array = array("a"=>"C", "b"=>"T", "c"=>"F");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
// 输出: $a=C; $b=T; $c=F
漏洞案例1:
$public = false;
extract($_GET); // 将数组键名转换为变量名
if($public == true) {
echo "bypass!!!<br>";
} else {
echo "try again<br/>";
exit(0);
}
// payload: ?public=true
2. parse_str()函数
将字符串解析成多个变量。
安全用法:
$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
危险用法:
$name = "tom";
parse_str("name=Bill&age=60");
echo $name."<br>"; // Bill
echo $age; // 60
注意:PHP 7.2.0后不带第二个参数的用法会产生E_DEPRECATED警告。
3. mb_parse_str函数
功能类似parse_str,解析GET/POST/COOKIE数据并设置全局变量。
4. import_request_variables函数
将GET/POST/Cookie变量导入到全局作用域。
import_request_variables("gP", "ee_");
echo $ee_knight;
注意:该函数从PHP5.3开始废弃,PHP5.4.0移除。
5. register_globals配置
当php.ini中register_globals = On时,传递的值会被直接注册为全局变量。
检测register_globals是否开启:
echo "Register_globals: ".(int)ini_get("register_globals")."<br/>";
if($auth){
echo "hello!";
}
版本变化:
- PHP4.2.0前默认On
- PHP5.3.0废弃
- PHP5.4.0移除
6. array_merge覆盖数组键
当数组有相同键名时,后面的值会覆盖前面的值。
$query = $_GET;
$arr = array("public"=>false, "name"=>'张三');
$query = array_merge($arr, $query);
if ($query["public"] == true){
echo "bypass!!!<br/>";
var_dump($query);
} else {
echo "try again<br/>";
var_dump($query);
exit(0);
}
// payload: ?public=true
7.
\[变量变量 ```php $var = "ee"; \]
var = "eeknight";
echo $var; // ee
echo "
";
echo
\[var; // eeknight
echo "
";
echo "$ee"; // eeknight
```
**漏洞案例**:
```php
$a = 1;
foreach(array('_COOKIE','_POST','_GET') as $_request) {
foreach(
\]
_request as \(_key=>\)_value) {
\[_key = addslashes($_value); } } echo $a; ``` ## 四、漏洞防御措施 1. **避免使用危险函数**:如extract()、parse_str()等 2. **使用安全替代方案**: - 使用带第二个参数的parse_str() - 避免直接使用extract()处理用户输入 3. **验证变量存在性**:在注册变量前先判断变量是否存在 4. **禁用危险配置**:确保register_globals=Off 5. **过滤用户输入**:使用addslashes()等函数处理输入 6. **更新PHP版本**:使用最新稳定版本PHP 7. **代码审计**:检查所有可能造成变量覆盖的代码点 ## 五、附加说明 1. **parse_str()**受php.ini中magic_quotes_gpc设置影响 2. **import_request_variables()**仅支持PHP 4 >= 4.1.0, PHP 5 < 5.4.0 3. **register_globals**从PHP5.3.0起废弃,PHP5.4.0移除 ## 六、参考链接 1. [PHP变量覆盖漏洞详解](https://mp.weixin.qq.com/s/z6B4luPfFDXihzhnOPd1MQ) 2. [FreeBuf文章](https://www.freebuf.com/articles/web/243339.html)\]