变量覆盖是指变量未被初始化,我们自定义的参数值可以替换原有的变量值
通常结合程序的其他漏洞实现完整的攻击,比如文件上传页面,覆盖掉原来白名单的列表,用户注册页面控制没覆盖的未初始化变量导致sql
常见危险函数
$$ extract() parse_str() import_request_variables()
<?php
$a =1;
foreach (array('_COOKIE','_POST','_GET') as $_request){
foreach($$_request as $_key => $_value){
$$_key = addslashes($_value);
}
}
echo $a;
?>
遍历初始化变量导致覆盖,这里将cookie,post,get通过变量方式赋值给
/
r
e
q
u
e
s
t
,
这里通过
g
e
t
方式传输变量
/_request,这里通过get方式传输变量
/request,这里通过get方式传输变量/_request=get,那么
/
/
//_request=
/
G
E
T
,
将
/_GET,将
/GET,将/_GET的变量参数赋值给key,get方式传个a变量,那么
/
k
e
y
=
a
,
/key = a ,
/key=a,/
/
k
e
y
=
/key=
/key=/a,a的变量覆盖成2
http://www.zy.com/test.php?a=2
extract()变量覆盖
int extract($array,extract_rules,prefix)
$array 关联的数组,受第二个和三个参数的影响
extract_rules 对待非法 /数字和冲突的键名的方法将根据取出标记
prefix 仅在第二个参数特殊时需要,添加前缀
参数 描述
array 必需。规定要使用的数组。
extract_rules
可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。
可能的值:
EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
EXTR_SKIP - 如果有冲突,不覆盖已有的变量。
EXTR_PREFIX_SAME - 如果有冲突,在变量名前加上前缀 prefix。
EXTR_PREFIX_ALL - 给所有变量名加上前缀 prefix。
EXTR_PREFIX_INVALID - 仅在不合法或数字变量名前加上前缀 prefix。
EXTR_IF_EXISTS - 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。
EXTR_PREFIX_IF_EXISTS - 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
EXTR_REFS - 将变量作为引用提取。导入的变量仍然引用了数组参数的值。
prefix
可选。请注意 prefix 仅在 extract_type 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。
前缀和数组键名之间会自动加上一个下划线。
$password = 'pwd';
$arr = array(
'username'->'username',
'password'->'password',
'rand'->'rand'
);
extract($arr,EXTR_PREFIX_SAME,"pwd");
echo $password;
echo $pwd_password;
数组中的password变量产生了冲突,被添加了pwd前缀,$password的值为pwd
第二种情况直接覆盖掉password的值
<?php
$password = 'pwd';
$arr = array(
'username'=>'username',
'password'=>'password',
'rand'=>'rand'
);
extract($arr,EXTR_OVERWRITE);
echo $password;
echo $pwd_password;
?>
第三种情况
<?php
$password = 'pwd';
$arr = array(
'username'=>'username',
'password'=>'password',
'rand'=>'rand'
);
extract($arr,EXTR_IF_EXISTS );
echo $password;
echo $pwd_password;
?>
也是直接覆盖password
parse_str()变量覆盖
parse_str(KaTeX parse error: Expected 'EOF', got '&' at position 14: string,[arrar&̲result])
$string 输入的字符串
$result 变量会以数组元素的形式存入到这个数组,作为替代
$a = 'a';
parse_str('a=b');
echo $a;
//这里如果未指定数组直接会覆盖掉a变量
import_request_variables() 函数将 GET/POST/Cookie 变量导入到全局作用域中。该函数在最新版本的 PHP 中已经不支持。
import_request_variables() 函数将 GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。
版本要求:PHP 4 >= 4.1.0, PHP 5 < 5.4.0
bool import_request_variables ( string $types [, string $prefix ] )
$types:指定需要导入的变量,可以用字母 G、P 和 C 分别表示 GET、POST 和 Cookie,这些字母不区分大小写,所以你可以使用 g 、 p 和 c 的任何组合。POST 包含了通过 POST 方法上传的文件信息。注意这些字母的顺序,当使用 gp 时,POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略。
$prefix: 变量名的前缀,置于所有被导入到全局作用域的变量之前。所以如果你有个名为 userid 的 GET 变量,同时提供了 pref_ 作为前缀,那么你将获得一个名为 $pref_userid 的全局变量。虽然 prefix 参数是可选的,但如果不指定前缀,或者指定一个空字符串作为前缀,你将获得一个 E_NOTICE 级别的错误。
$a =1;
import_request_variables("G");//将get的传过来的变量注册为全局变量
if($a==2){
echo "sucess";}
else{
echo "fail";
}
修复
ctf题变量覆盖
这里将$_200的值覆盖成flage的值在输出就成
exp : http://ww.test.com/ctf.php?_200=flag 在post flag=123