这里我们着重了解一下变量覆盖
首先我们要知道函数是什么
foreach
foreach (iterable_expression as $value)statement
foreach (iterable_expression as $key => $value)statement第一种格式遍历给定的 iterable_expression 迭代器。每次循环中,当前单元的值被赋给 $value。第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 $key。
不一样只是键名是否赋值
数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。
变量覆盖
这个其实很简单 就是有点绕
<?php
$ary=array('a','b','c','c','e');
foreach($ary as $key=>$value){ //$ary的键名赋给$key,键值赋给$value$$key=$value; //把键值赋给$$key
}
print_r($key); //输出4
因为 数组为5 那么就是有 01234个值 这里就会将 $ary的值存入 就是4
print_r($value); //输出e
因为经过遍历 所以这里是指向最后一个值 就是 $arr[4]=eprint_r($$key); //输出e
最后 $$key=$value类似于
$(key)=value
所以输出$$key 就会输出 $(key) 就会输出 value =e?>
已经感觉类似渗透了
直接dir扫一下
一下就想到git泄露
我们直接 githack
直接看看源代码
flag.php
index.php
这里存在echo 我们直接去看看网站哪里存在输出了
然后我们就可以确定现在输出的是$yds变量 我们开始代码审计
分析
1.输出是dog 那么就是$yds
只有在
if(!isset($_GET['flag']) && !isset($_POST['flag'])){exit($yds);
}
会输出yds 所以我们需要传递 POST GET参数
我们思考完这个 我们想想看如何可以让 flag输出
我们可以通过 exit()输出flag值
首先这里是输出yds那么很简单我们get的参数就是 yds$$yds但是输出的是 $yds所以我们只需要让 $yds=$flag 就可以变相exit($flag)了$$yds=$$flag就类似于$(yds)=$(flag)所以我们只需要传递 yds=flag即可/?yds=flag
第二种
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){exit($is);
}这里存在 post的值绝对为flag 或者 get的值绝对为flag
我们首先看post
flag=flag$x=$flag=flag
这样就失去了变量 所以无法
接着我们看看get
flag=flag
$$flag=$flag=$flag因为我们要输出is所以?is=flag现在这里是 $(is)=$(flag)然后跟上 &flag=flag这样的话$(flag)=$(flag)最后转换还是$(is)=$(flag)这样就可以输出了
这样就可以输出flag了
/?is=flag&flag=flag
第三种
foreach($_GET as $x => $y){if($_GET['flag'] === $x && $x !== 'flag'){exit($handsome);}
}get的flag值绝对为 $x 并且 $x不为 flag
我们还是确定我们需要输出 handsome所以我们构造 ?handsome=flag这样$(handsome)=$(flag)然后就会去看看$flag是啥 但是这里$不能为flag我们在中间搭建一个桥梁即可?handsome=flag&flag=b&b=flag这样$(handsom)=$(flag)
然后
$flag=$b
就绕过了!==判断然后$(b)=flag这里别的师傅有更简单的思路?flag=a&&a!=flag所以我们构造一个中间值传递参数即可