干货|一文带你了解PHP变量覆盖
字数 1098 2025-08-11 08:35:50

PHP变量覆盖漏洞详解

一、变量覆盖定义

变量覆盖指的是通过用户传入的参数值替换程序原有变量值的漏洞。这种漏洞可以导致修改关键变量的值,进而造成越权访问、写入webshell等严重危害。

二、变量覆盖的风险

  1. 越权访问:如Joomla未授权访问漏洞(CVE-2023-23752)
  2. 写入webshell
  3. 绕过权限检查
  4. 修改程序逻辑

三、变量覆盖常见场景

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)\]

PHP变量覆盖漏洞详解 一、变量覆盖定义 变量覆盖指的是通过用户传入的参数值替换程序原有变量值的漏洞。这种漏洞可以导致修改关键变量的值,进而造成越权访问、写入webshell等严重危害。 二、变量覆盖的风险 越权访问 :如Joomla未授权访问漏洞(CVE-2023-23752) 写入webshell 绕过权限检查 修改程序逻辑 三、变量覆盖常见场景 1. extract()函数 extract() 函数将数组中的键名转换为变量名,键值作为变量值。 漏洞案例1 : 2. parse_ str()函数 将字符串解析成多个变量。 安全用法 : 危险用法 : 注意 :PHP 7.2.0后不带第二个参数的用法会产生E_ DEPRECATED警告。 3. mb_ parse_ str函数 功能类似parse_ str,解析GET/POST/COOKIE数据并设置全局变量。 4. import_ request_ variables函数 将GET/POST/Cookie变量导入到全局作用域。 注意 :该函数从PHP5.3开始废弃,PHP5.4.0移除。 5. register_ globals配置 当php.ini中 register_globals = On 时,传递的值会被直接注册为全局变量。 检测register_ globals是否开启 : 版本变化 : PHP4.2.0前默认On PHP5.3.0废弃 PHP5.4.0移除 6. array_ merge覆盖数组键 当数组有相同键名时,后面的值会覆盖前面的值。 7. $$变量变量 漏洞案例 : 四、漏洞防御措施 避免使用危险函数 :如extract()、parse_ str()等 使用安全替代方案 : 使用带第二个参数的parse_ str() 避免直接使用extract()处理用户输入 验证变量存在性 :在注册变量前先判断变量是否存在 禁用危险配置 :确保register_ globals=Off 过滤用户输入 :使用addslashes()等函数处理输入 更新PHP版本 :使用最新稳定版本PHP 代码审计 :检查所有可能造成变量覆盖的代码点 五、附加说明 parse_ str() 受php.ini中magic_ quotes_ gpc设置影响 import_ request_ variables() 仅支持PHP 4 >= 4.1.0, PHP 5 < 5.4.0 register_ globals 从PHP5.3.0起废弃,PHP5.4.0移除 六、参考链接 PHP变量覆盖漏洞详解 FreeBuf文章