前言
做[GDOUCTF 2023]受不了一点这道题时想到的一些知识补充
遂记录下来
正文
在本地php环境上进行实验
页面源码
<?php
$flag='Thisisflag';
foreach ($_POST as $key => $value) {
$$key = $value;
}
foreach ($_GET as $key => $value) {
$$key = $$value;
}
print_r(get_defined_vars());
echo "\n";
echo $flag;
为了能够直观的查看各个变量的值,这里使用get_defined_vars()
函数返回一个包含所有已定义变量列表的多维数组
foreach()
语句能把post/get进去的数组键名作为变量,数组中的键值作为变量的值
打开页面
可以看到目前的全部变量以及flag值的回显
然后我们传入get请求?flag=1
可以发现此时$key->flag
,$flag->$value->1
,但是flag的值并没有回显,为什么呢?
原因是在get请求的foreach语句中,$$key=$$value
,于是我们传进去的参数会变成$flag=$1
,但是$1
并没有被赋值,所以没有回显
而post请求的foreach语句是$$key=$value
那我们就单独post请求传一个flag=1
看看会发生什么
可以看到回显的$flag
变成了1
原因是我们传进去的post请求参数会变成$key->flag
,$value->1
,那么post的foreach执行语句就会变成$flag=1
,所以会回显1
现在我们同时get传入?flag=1
,post传入1=flag
看看会发生什么
很明显这里$flag
的值为flag,因为实际foreach语句中为$flag=$1
,$1=flag
,所以这样子会导致$flag
变量被覆盖
现在我们对回显加一个限制
if(isset($_GET['flag'])){
if($_GET['flag']=$flag){
echo $flag;
}
}
再看看get传入1=flag
和flag=1
的效果
此时$1=$flag='Thisisflag'
,然后$flag=$1
,这样子$flag
内的值没有发生改变可以直接匹配’Thisisflag’于是成功回显
总结
变量覆盖的大致思路就是这样,限于本人思维能力,本篇文章叙述表达可能不大清晰555