目录

  1. 1. 前言
  2. 2. 正文
    1. 2.1. 页面源码
  3. 3. 总结

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

变量覆盖的一次探索

2023/4/25 Web PHP
  |     |   总文章阅读量:

前言

[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进去的数组键名作为变量,数组中的键值作为变量的值

打开页面

image-20230426004621030

可以看到目前的全部变量以及flag值的回显

然后我们传入get请求?flag=1

image-20230426005323417

可以发现此时$key->flag,$flag->$value->1,但是flag的值并没有回显,为什么呢?

原因是在get请求的foreach语句中,$$key=$$value,于是我们传进去的参数会变成$flag=$1,但是$1并没有被赋值,所以没有回显

而post请求的foreach语句是$$key=$value

那我们就单独post请求传一个flag=1看看会发生什么

image-20230426095709508

可以看到回显的$flag变成了1

原因是我们传进去的post请求参数会变成$key->flag,$value->1,那么post的foreach执行语句就会变成$flag=1,所以会回显1

现在我们同时get传入?flag=1,post传入1=flag看看会发生什么

image-20230426005418362

很明显这里$flag的值为flag,因为实际foreach语句中为$flag=$1$1=flag,所以这样子会导致$flag变量被覆盖

现在我们对回显加一个限制

if(isset($_GET['flag'])){
    if($_GET['flag']=$flag){
        echo $flag;
    }
}

image-20230426143550954

再看看get传入1=flagflag=1的效果

image-20230426143508655

此时$1=$flag='Thisisflag',然后$flag=$1,这样子$flag内的值没有发生改变可以直接匹配’Thisisflag’于是成功回显

总结

变量覆盖的大致思路就是这样,限于本人思维能力,本篇文章叙述表达可能不大清晰555