变量覆盖
变量覆盖(Dynamic Variable Evaluation)是指变量未被初始化,我们自定义的参数值可以替换程序原有的变量值
漏洞危害
通常结合程序的其它漏洞实现完整的攻击,比如文件上传页面,覆盖掉原来白名单的列表,导致任意文件上传;用户注册页面控制没覆盖的未初始化变量导致SQL
挖掘经验
常见危险函数
$$、extract()函数、import_request_variables()函数、parse_str()函数执行
遍历初始化变量
常见的遍历方式释放代码,可能导致变量覆盖漏洞
extract()变量覆盖
原型:
int extract ( $array , extract_rules,prefix )
- $array 关联的数组,受第二个和第三个参数的影响。
- extract_rules 对待非法/数字和冲突的键名的方法将根据取出标记
- prefix 仅在第二个参数特殊时需要,添加前缀
危险函数(第二个参数)
- EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
- EXTR_SKIP - 如果有冲突,不覆盖已有的变量。(忽略数组中同名的元素)
- EXTR_PREFIX_SAME - 如果有冲突,在变量名前加上前缀 prefix。自 PHP 4.0.5 起,这也包括了对数字索引的处理
- EXTR_PREFIX_ALL - 给所有变量名加上前缀 prefix(第三个参数)
- EXTR_PREFIX_INVALID - 仅在非法或数字变量名前加上前缀 prefix。本标记是 PHP 4.0.5 新加的。
- EXTR_IF_EXISTS - 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。可以用在已经定义了一组合法的变量,然后要从一个数组例如 $_REQUEST 中提取值覆盖这些变量的场合。本标记是 PHP 4.2.0 新加的。
- EXTR_PREFIX_IF_EXISTS - 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。本标记是 PHP 4.2.0 新加的。
- EXTR_REFS - 将变量作为引用提取。这有力地表明了导入的变量仍然引用了 var_array 参数的值。可以单独使用这个标志或者在 extract_type 中用 OR 与其它任何标志结合使用。本标记是 PHP 4.3.0 新加的。
实例
第一种情况(EXTR_PREFIX_SAME)
password被覆盖为pwd
第二种情况(EXTR_OVERWRITE)
第三种情况(EXTR_IF_EXISTS)
直接覆盖
parse_str()变量覆盖
原型:
void parse_str ( string $encoded_string [, array &$result ] )
- $encoded_string 输入的字符串
- $result 变量将会以数组元素的形式存入到这个数组,作为替代
实例
直接赋值,不会检测是否定义一个a变量
import_request_variables()函数
(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)
import_request_variables — 将 GET/POST/Cookie 变量导入到全局作用域中
原型:
bool import_request_variables ( string $types [, string $prefix ] )
- $type 指定需要导入的变量。可以用字母‘G’、‘P’和‘C’分别表示 GET、POST 和 Cookie
- $prefix 变量名前缀
实例
修复方案
- 在php.ini文件中设置register_globals=OFF
- 使用原始变量数组,如$_POST,$_GET等数组变量进行操作
- 不使用foreach语句来遍历$_GET变量,而改用[(index)]来指定
- 验证变量是否存在,注册变量前先判断变量是否存在