0x01 变量覆盖
1.1 extract()
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。条件:若有EXTR_SKIP则不行。
一个简单的变量覆盖的例子:
<?php
$a = 1; //原变量值为1
$b = array('a' => '3');
extract($b); //经过extract()函数对$b处理后
echo $a; //输出结果为3
?>
1.2 例题
<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan))
{
$content=trim(file_get_contents($flag)); # content is 0 , flag can be anything,cause file_get_contents cannot open file, return 0
if($shiyan==$content)
{
echo'ctf{xxx}';
}
else
{
echo'Oh.no';
}
}
payload:
?shiyan=&flag=1
这里的=&
就相当于取得别名,数据地址均为一致的
1.3 parse_str()
解析字符串并注册成变量
$b=1;
Parse_str('b=2');
Print_r($b);
结果: $b=2
1.4 import_request_variables()
将 GET/POST/Cookie 变量导入到全局作用域中,全局变量注册。
在5.4之后被取消,只可在4-4.1.0和5-5.4.0可用。
//导入POST提交的变量值,前缀为post_
import_request_variable("p", "post_");
//导入GET和POST提交的变量值,前缀为gp_,GET优先于POST
import_request_variable("gp", "gp_");
//导入Cookie和GET的变量值,Cookie变量值优先于GET
import_request_variable("cg", "cg_");
1.5 $$变量覆盖
提交参数chs,则可覆盖变量"$chs"的值。$key为chs时,$$key就变成$chs
<?
$chs = '';
if($_POST && $charset != 'utf-8'){
$chs = new Chinese('UTF-8', $charset);
foreach($_POST as $key => $value){
$$key = $chs->Convert($value);
}
unset($chs);
}
1.6 全局变量覆盖漏洞
原理: register_globals 是php中的一个控制选项,可以设置成off或者on, 默认为off, 决定是否将 EGPCS(Environment,GET,POST,Cookie,Server)变量注册为全局变量。 如果register_globals打开的话, 客户端提交的数据中含有GLOBALS变量名, 就会覆盖服务器上的$GLOBALS变量.
$_REQUEST 这个超全局变量的值受 php.ini中request_order的影响,在php5.3.x系列中,request_order默认值为GP,也就是说默认配置下$_REQUEST只包含$_GET和$_POST而不包括$_COOKIE。通过COOKIE就可以提交GLOBALS变量。
<?php
// register_globals =ON
//foo.php?GLOBALS[foobar]=HELLO
echo $foobar;
//为了安全取消全局变量
//var.php?GLOBALS[a]=aaaa&b=111
if (ini_get("register_globals")) foreach($_REQUEST as $k=>$v) unset(${$k});
print $a;
print $_GET[b];
?>
经过测试,开了register_globals会卡死
0x02 绕过过滤的空白字符
下午再搞~