<?php include "flag.php"; $yds = "dog"; $is = "cat"; $handsome = 'yds'; foreach($_POST as $x => $y){//将$_POST传递的数据当成一个数组(我更愿意叫它字典,其实就是一个个键值对)并遍历 $$x = $y;//$$相当于将变量值化为变量名,例如:$x='handsome',$$x就相当于$handsome, //这里将每个值变为一个变量,并赋原值,如传递?flag='handsome',到这一步就是 $handsome = 'handsome' //容易发现我们可以利用此处,任意创建变量并赋值,存在变量覆盖漏洞 } foreach($_GET as $x => $y){//同上理解即可 $$x = $$y; } foreach($_GET as $x => $y){ if($_GET['flag'] === $x && $x !== 'flag'){ exit($handsome); //这里exit函数打印了handsome变量,利用变量覆盖漏洞,将$handsome的值改为$flag的值 //payload为?handsome=flag&flag=handsome } } if(!isset($_GET['flag']) && !isset($_POST['flag'])){ exit($yds); } if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ exit($is); } echo "the flag is: ".$flag;
时间: 2025-03-09 11:10:03 浏览: 71
<think>好的,我现在需要分析这个PHP代码,看看如何获取到$flag变量的值。首先,我会通读整个代码,理解每个部分的作用,然后找出可能的漏洞点。
首先,代码开头包含了flag.php,里面可能定义了$flag变量,存储着需要获取的flag。接下来,定义了三个变量:$yds = "dog",$is = "cat",$handsome = 'yds'。这里注意,$handsome的值是字符串'yds',而不是变量$yds的值。
接下来有三个foreach循环处理$_POST和$_GET数据。第一个foreach处理$_POST,使用$$x = $y,这存在变量覆盖漏洞,因为用户传入的POST参数名会被当作变量名,值直接赋给该变量。例如,如果POST参数是x=abc,那么会创建变量$x并赋值为abc。
第二个foreach处理$_GET,代码是$$x = $$y。这里更危险,例如,如果GET参数是x=y,那么就会把变量$y的值赋给变量$x。比如,如果y是handsome,那么$x就会被赋值为$handsome的值,即'yds'。不过,如果用户传入的参数y是一个已存在的变量名,比如flag,那么$$y就是$flag的值,这样就可以将其他变量覆盖为$flag的值。
第三个foreach同样处理$_GET,检查是否存在某个GET参数,当$_GET['flag']等于参数名x,并且x不等于'flag'时,就exit($handsome)。所以,如果能让$_GET['flag']的值等于某个参数名x,并且x不是'flag',那么就会输出$handsome的值。这时候如果能让$handsome等于$flag,就能得到flag。
接下来的条件判断,如果没有GET或POST的flag参数,就exit($yds),也就是输出"dog"。如果POST或GET的flag参数的值是'flag',就exit($is),即输出"cat"。最后,如果前面的条件都没触发,就会输出$flag,但正常情况下可能无法到达这里,因为有前面的exit。
现在需要构造payload,使得在第三个foreach中触发exit($handsome),并且此时$handsome的值是$flag。如何做到这一点呢?
首先,利用变量覆盖漏洞。在第二个foreach中,处理GET参数时,$$x = $$y。假设我们传入一个GET参数,比如handsome=flag。这里,x是handsome,y是flag。那么执行后,$handsome = $flag。这样,$handsome变量就被赋值为$flag的值了。
接下来,第三个foreach中需要满足$_GET['flag'] === $x且$x !== 'flag'。假设我们传入flag=handsome,那么这里的$x是参数名,比如另一个参数,比如a=xxx,但这样可能不太行。或者,在第三个foreach中遍历GET参数时,当处理到参数x=handsome时,检查是否$_GET['flag']等于x的值。例如,如果我们传入?handsome=flag&flag=handsome,那么:
在第二个foreach中,处理handsome=flag时,$$x(即$handsome)被赋值为$$y(即$flag)。这样,$handsome = $flag的值。
然后,处理flag=handsome时,$$x(即$flag)被赋值为$$y(即$handsome,此时已经是$flag的值)。不过这可能不重要,因为之后在第三个foreach中,检查每个GET参数。假设现在GET参数有两个:handsome=flag和flag=handsome。在遍历到x=flag时,y=handsome。此时,$_GET['flag']的值是'handsome',而$x是'flag'。所以判断条件是'handsome' === 'flag'吗?不,不是。这里可能需要更仔细的分析。
第三个foreach循环遍历每个GET参数。对于每个参数x => y,检查$_GET['flag']是否等于x,并且x不等于'flag'。如果满足,就exit($handsome)。
假设我们的payload是:?handsome=flag&flag=handsome。这里有两个GET参数:
第一个参数是handsome=flag。在第二个foreach中,处理这个参数时,x是handsome,y是flag,所以$$x = $$y → $handsome = $flag的值。
第二个参数是flag=handsome。处理这个参数时,x是flag,y是handsome,所以$$x = $$y → $flag = $handsome。但此时$handsome已经被赋值为$flag的值,所以这一步可能导致$flag被覆盖为自身的值,可能没有实际变化。
现在进入第三个foreach,遍历GET参数:
第一个参数是handsome=flag。此时x是'handsome',y是'flag'。检查$_GET['flag']的值是否是'handsome'?因为$_GET['flag']的值是我们在第二个参数中传入的'handsome'。因此,此时$_GET['flag']的值是'handsome',而当前的x是'handsome'。所以条件判断是:$_GET['flag'] === x → 'handsome' === 'handsome',并且x !== 'flag' → 成立。因此,会执行exit($handsome)。而此时的$handsome已经被第二个foreach中的处理赋值为$flag的值,所以会输出$flag的值。
这样,payload应该是:通过GET传递两个参数,handsome=flag和flag=handsome。这样就能触发第三个foreach中的exit($handsome),此时$handsome已经被设置为$flag的值,从而得到flag。
所以最终的payload应该是:GET请求传入?handsome=flag&flag=handsome,这样就能让$handsome等于$flag,并触发exit($handsome),从而输出flag。</think>让我们逐步分析这段PHP代码,并找到获取flag的方法:
1. **变量覆盖漏洞分析**:
- `$$x = $y`(POST处理)和`$$x = $$y`(GET处理)存在变量覆盖漏洞
- 可以通过参数控制任意变量值,例如:
- 传入`?a=b`会创建变量`$a = 'b'`
- 传入`?handsome=flag`会让`$handsome = $flag`
2. **关键退出点分析**:
```php
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
```
需要同时满足:
- GET参数中存在名为flag的参数
- flag参数的值等于某个参数名
- 该参数名不能是"flag"
3. **构造Payload**:
```url
?handsome=flag&flag=handsome
```
执行流程:
- 第一个GET参数`handsome=flag` ➔ `$handsome = $flag`
- 第二个GET参数`flag=handsome` ➔ 满足判断条件:
- `$_GET['flag']`值为"handsome"
- 遍历到第一个参数时`$x="handsome"`
- 触发`exit($handsome)`输出`$flag`的值
4. **测试验证**:
访问携带payload的URL后,服务器会直接返回flag值,例如:
```plaintext
flag{this_is_a_sample_flag}
```
**注意事项**:
1. 该漏洞属于典型的变量覆盖漏洞
2. 代码中多个危险操作组合导致漏洞产生
3. 开发中应避免使用可变变量($$var)处理用户输入
阅读全文
相关推荐

















