欢迎关注我的微信公众号《壳中之魂》观看更多网安文章
变量覆盖,顾名思义,就是将原来变量的值给覆盖掉,变量覆盖漏洞有的时候可以直接让我们获取Webshell,拿到服务器的权限
一般造成变量覆盖的写法有
<?php
$_200 = "Welcome Admin";
$_403 = "Access Denied";
$var = "_403";
foreach ($_GET as $key => $value){
echo $key."<br>";
echo $$key."<br>";
}
echo $var."<br>";
echo $$var."<br>";
?>
传入?var=_200
,输出
var
_403
_403
Access Denied
从中有几点需要注意,首先就是$$的性质;跟着是$key=var=$$var
,然而这个$var
的值并不会被url的传值给改变,因为没有赋值,所以$$var
其实还是取回原来的值,也就是_403
,而不是_200
<?php
$flag = "This is a flag";//内容不可知
$_403 = "Access Denied";
$_200 = "Welcome Admin";
foreach ($_GET as $key => $value)
$$key = $$value;
if ( $_POST["flag"] !== $flag )
die($_403);
echo "This is your flag : ". $flag . "<br>";
die($_200);
?>
此代码目的是为了输出$flag
的值,想要达到目的就需要满足$_POST["flag"] === $flag
,即值和类型都要相等,突破点就在
foreach ($_GET as $key => $value)
$$key = $$value;
首先代码会经过第一个foreach,审计一下
foreach ($_GET as $key => $value)
$$key = $$value;
经过审计,判断可以利用该代码来修改代码里面变量的值,如传入?_403=flag
,即可吧$_403
的值修改为$flag
的值,分析一下:
$key = _403 $value=flag
$$key = $_403 $$value = $flag
所以最终的结果就变为了$_403=$flag
所以接下来只需要满足if ($_POST["flag"] === $flag)
,就会输出$_403
的值,但是$_403
的值已经被覆盖为了$flag
的值
此函数的作用是extract() 函数从数组中将变量导入到当前的符号表,该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量,看一个简单的示例
<?php
$a = "Original";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
一般来说想要输出关联数组,需要以$my_array['a']
这样的形式输出,但是通过extract()函数后,可以直接通过将其键以变量的形式打印来输出对对应的值
首先先看一下代码,假如想要此代码输出flag的内容,理论上需要知道$content
的值,即trim($test, "!!")
,然后再传入gift与其相等
<?php
$flag = "flag";//内容不可知
$test = "This is a Test!!";
extract($_GET);
if(isset($gift)){
$content = trim($test, "!!");
if($gift == $content){
echo'flag is:'.$flag;
}
}else{
echo "error";
}
?>
但是通过变量覆盖漏洞,就可以即使不知道$test
的值,也可以去让这个表达式成立,重点是将test的值修改了
?gift=flag&test=flag
分析一下,我们传入的值为gift=flag&test=flag
,经过extract($_GET);
执行后,$gift=flag
,同时$test
也为flag,在trim($test, "!!");
,语句不会匹配到,所以flag不会被修改传入进去;虽然一开始$test
的值为This is a Test!!
,但是PHP由上至下执行,所以在后面被覆盖后值就被改变了
parse_str(string,array)
string 必需。规定要解析的字符串。
array 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。
看一下示例:
<?php
$str = "name=g1ts&age=18";
@parse_str($str);
echo $name."<br>".$age;
?>
输出
g1ts
18
如果该函数写法为parse_str($_GET);
,那么就可以通过传入参数来改变代码里面原有的参数值
<?php
$name = "admin";
$age = 0;
@parse_str($_GET['var']);
echo $name."<br>".$age;
?>
但是有一点要注意,var=name=g1ts%26age=18
中的&(%26)一定要url编码,也就是写成%26的形式,要不然后面的参数接受不了
mb_parse_str(string $encoded_string, array &$result = ?): bool
解析 GET/POST/COOKIE 数据并设置全局变量。 由于 PHP 不提供原始 POST/COOKIE 数据,目前它仅能够用于 GET 数据。 它解析了 URL 编码过的数据,检测其编码,并转换编码为内部编码,然后设置其值为 array 的 result 或者全局变量。
$str = 'email=kehaovista@qq.com&city=shanghai&job=Phper';
mb_parse_str($str, $result);
print_r($result);
//结果
Array
(
[email] => kehaovista@qq.com
[city] => shanghai
[job] => Phper
)
利用思路和parse_str函数差不太多
import_request_variables() 函数将 GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。该函数在最新版本的 PHP 中已经不支持。
//导入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_");
<?php
// 此处将导入 GET 和 POST 变量
import_request_variables("gP", "g1ts_");
echo $g1ts_me;
?>
输出
图片
利用思路和parse_str函数差不太多
深信服EDR RCE:https://www.yuque.com/tianxiadamutou/xqp4q6/bv4t2u
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。