题目如下:
首先对php代码进行审计:
$flag=’xxxxxxx‘可不是代表flag的值是xxx,这段代码是通过第一行的代码:highlight_file('source.txt');把source.txt中的内容显示在了界面上,真实flag的值隐藏了起来,这里专门写出的意义是提醒同学们最后要得到的flag在$flag中。
这一行代码首先使用isset()
函数检查$_GET['flag']
和$_POST['flag']
两个变量是否存在。如果两者都不存在,则执行exit($giveme)
,脚本输出$giveme
变量的值并终止执行。
这一行代码检查$_POST['flag']
和$_GET['flag']
两个变量是否等于字符串'flag'
。如果其中任何一个变量的值为'flag'
,则执行exit($getout)
,脚本输出$getout
变量的值并终止执行。值得注意的是这里的判断是===。
这部分代码使用foreach分别
循环遍历$_POST
数组和$_GET
数组。对于每个键值对,在$_POST
数组中,将键作为变量名,将对应的值作为变量值。在$_GET数组中,
对于每个键值对,将值作为变量名,并将对应变量的值赋给当前循环的变量。这里是题的关键所在,如何理解这个$$,可以参照下例:
让我们假设URL为:http://example.com?name=John&age=25
在这种情况下,$_GET
数组如下:
$_GET = array(
'name' => 'John',
'age' => '25'
);
现在,如果我们使用该foreach循环来遍历$_GET
数组:
foreach ($_GET as $key => $value) {
$$key = $value;
}
该循环将创建两个变量$name
和$age
,并将它们的值分别设置为’John’和’25’。
因此,上述代码等效于以下赋值操作:
$name = 'John';
$age = '25';
现在,我们可以直接使用这些变量$name
和$age
来访问相应的值:
echo $name; // 输出:John
echo $age; // 输出:25
理解之后,在加上之前的判断,我们可以得出答案:?a=flag&flag=a.
实际的过程是$a = $flag,随后$flag = $a = $flag,即flag的值没有发生变化,且满足上述的需求。