本文记录 PHP 代码审计的学习过程,教程为暗月 2015 版的 PHP 代码审计课程
1. 简介
产生原因
是 register_globals 为on 的情况,PHP4 默认开启,PHP5 以后默认关闭。
从 PHP > 4.2.0 版开始配置文件中 PHP 指令 register_globals 的默认值从 on 改为 off 了,自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。源自 http://php.net/manual/zh/security.globals.php
是人为注册成为全局变量
经常导致变量覆盖漏洞场景有:$$,extract()函数,parse_str()函数,import_request_variables()使用不当
全局变量的取值与赋值简介
<?php echo $a='a'; echo "<hr>"; echo $GLOBAL['a']='b'; echo "<hr>"; echo $a; ?>
2. 测试
register_globals 为on 的情况
已废止,环境未搭建成功
$$导致的变量覆盖问题
使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?id=1 会将 id=1。
<?php foreach (array('_COOKIE','_POST','_GET') as $_request) { foreach ($$_request as $_key=>$_value) { $$_key= $_value; } } $id = isset($id) ? $id : 2; if($id == 1) { echo "flag{xxxxxxxxxx}"; die(); } echo $id; ?>
浏览器执行 http://127.0.0.1/test.php?id=1
小记:在代码审计时需要注意类似“$$k”的变量赋值方式有可能覆盖已有的变量,从而导致一些不可控制的结果。
extract()变量覆盖
extract() 函数从数组中将变量导入到当前的符号表。该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
tips: 在调用 extract() 时使用 EXTR_SKIP 保证已有变量不会被覆盖 extract($_GET,EXTR_SKIP);
示例一:
将键值 “Cat”、”Dog” 和 “Horse” 赋值给变量 b 和 $c
<?php $a = "Original"; $my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse"); extract($my_array); echo "\$a = $a; \$b = $b; \$c = $c"; ?>
示例二:
<?php $id=1; extract($_GET); echo $id; ?>
小记:PHP extract() 函数从数组中把变量导入到当前的符号表中。对于数组中的每个元素,键名用于变量名,键值用于变量值。
parse_str()变量覆盖
parse_str() 函数把查询字符串解析到变量中,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。
tips:parse_str()类似的函数还有mb_parse_str(),用法基本一致。
<?php parse_str("a=1"); echo $a."<br/>"; //$a=1 parse_str("b=1&c=2",$myArray); print_r($myArray); //Array ( [c] => 1 [b] => 2 ) ?>
浏览器执行 http://127.0.0.1/test.php
与parse_str()类似的函数还有mb_parse_str()
小记:parse_str — 将字符串解析成多个变量,如果参数str是URL传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域。
import_request_variables变量覆盖
import_request_variables 函数可以在 register_global = off 时,把 GET/POST/Cookie 变量导入全局作用域中。
<?php import_request_variables("g", "get_"); echo $get_id; ?>
http://127.0.0.1/test.php?id=111
结果显示 111
小记:import_request_variables — 将 GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。