变量覆盖是指利用自定义的参数值替换掉原有的变量值。变量覆盖漏洞通常需要结合代码中的其他功能来实现完整的攻击。
常见可导致变量覆盖漏洞的函数或方法有PHP超全局变量、register_globals、$$、parse_str()函数使用不当、extract()、import_request_variables()等。
1) PHP超全局变量
http://php.net/manual/zh/language.variables.superglobals.php
PHP 中的许多预定义变量都是“超全局的”,在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们。
2019年1月11日ThinkPHP 5.0.x~5.2x爆出的远程代码执行漏洞就与$_POST变量覆盖相关。
这些超全局变量是:1
2
3
4
5
6
7
8
9$GLOBALS 包含了全部变量的全局组合数组。
$_SERVER 包含服务器和执行环境等信息的数组。
$_GET 通过 URL 参数传递给当前脚本的变量的数组
$_POST 当 HTTP POST 请求的 Content-Type 是 application/x-www-form-urlencoded 或 multipart/form-data 时,会将变量以关联数组形式传入当前脚本。
$_FILES HTTP 文件上传变量。通过 HTTP POST 方式上传到当前脚本的项目的数组。
$_COOKIE 通过 HTTP Cookies 方式传递给当前脚本的变量的数组
$_SESSION 当前脚本可用 SESSION 变量的数组
$_REQUEST 默认情况下包含了 $_GET,$_POST 和 $_COOKIE 的数组
$_ENV 通过环境方式传递给当前脚本的变量的数组
1 | <?php |
2) register_globals
http://php.net/manual/zh/security.globals.php
当php.ini 中register_globals= On时 设置注册全局变量,将传递过来的值直接注册为全局变量并可直接使用。(必须是之前没有声明的变量,如果之前变量已经存在就无法覆盖)。
该特性从PHP 4.2.0开始将register_globals默认值设置为off,自 PHP 5.3.0 起废弃,自 PHP 5.4.0 起移除。
1 | <?php |
1 | 请求: xxx.php?www=1 |
3) $$
$$ 导致的变量覆盖常在foreach中出现,使用foreach来遍历数组中的值,然后将获取到的数组键名作为变量名,数组中的键值作为变量的值。1
2
3
4
5
6
7
8
9
10
11
12
13<?php
$id = 0;
foreach (array('_COOKIE','_POST','_GET') as $_request)
{
foreach ($$_request as $_key=>$_value)
{
//echo $_key."</br>";
$$_key= addslashes($_value); //GET: ?id=1 覆盖掉之前$id得值 现在id值为1
}
}
echo $id; //GET: xxx.php?id=1 输出1
?>
4) parse_str()
parse_str ( string $encoded_string [, array &$result ] )
如果 encoded_string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域
当没有result 参数时,可造成变量覆盖,在 PHP 7.2 中废弃不设置参数的行为。
推荐的安全写法:设置第二个变量 result, 变量将会以数组元素的形式存入到这个数组。
不安全写法:
1 | <?php |
推荐的安全写法:
1 | <?php |
5) extract()
extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] )
将变量从数组中导入到当前的符号表中
参数 array一个关联数组。此函数会将键名当作变量名,值作为变量的值。 对每个键/值对都会在当前的符号表中建立变量。
1 | <?php |
6) import_request_variables()
import_request_variables ( string $types [, string $prefix ] )
(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)
将 GET/POST/Cookie 变量导入到全局作用域中。
可以用字母‘G’、‘P’和‘C’分别表示 GET、POST 和 Cookie。不区分大小写。
1 | <?php |
参考:
https://p0sec.net/index.php/archives/35/ PHP变量覆盖漏洞总结
https://paper.tuisec.win/detail/85acab5a4db60f4 由MetInfo 深入理解PHP变量覆盖漏洞