foreach函数是PHP中用于遍历数组或对象的函数(且仅用于数组的遍历)。它允许循环遍历数组中的每个元素,并对每个元素执行相同的操作。foreach语句的基本语法如下:
foreach ($array as $value) {
//执行的操作
}
在这个语法中,$array
是要遍历的数组,$value
是当前循环的元素的值,在循环中,当前单元的值赋给$value,数组内部指针指向下一个单元
另一种语法
foreach ($array as $key => $value) {
// 执行的操作
}
在这种情况下,$key
是当前循环的元素的键,$value
是当前循环的元素的值。通过这种方式,可以方便地访问数组中的键和值,进行一个键值的匹配。
当foreach函数开始执行时,内部指针会自动指向数组的第一个单元,因此不用去特意指定开始的位置
变量覆盖:在PHP中,变量覆盖指的是在同一作用域内多次声明同名变量时,后面的变量声明将覆盖前面的变量声明。这意味着后面的变量将取代前面的变量,并且前面的变量将不再可用。
变量覆盖漏洞产生的原因:
1.$$导致的变量覆盖:
php中$$表示的是一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。
<?php
$a=array("a","b","c","d");
foreach($a as $key=>$value){//键名赋给$key,键值赋给$value
$$key=$value;//键值又赋给$$key
}
print_r($$key);
print_r($value);
print_r($key);
?>
可能这个逻辑有点昏头,用个例题来举例应该会好理解一些
[MoeCTF 2022]ezphp
目的是拿到flag,要在echo的位置成功输出$flag,但是前面if语句做出了限制,导致传参呢不能直接传入flag,否则就报错,这时候就需要变量覆盖来使得flag=flag,看到foreach函数,遍历了两个数组,一个GET 数组,一个POST数组,区别在哪里呢,在$符号,如果按照POST数组传入a=1
最后$$key=1,再不能最终实现flag=flag;
看到GET数组,当传入a=1时,最终解析出来的还是a=1,所以这时传入a=flag&flag=a,最终得到的是flag=a=flag,满足了flag=flag的条件,所以payload为?a=flag&flag=a