??变量覆盖漏洞可以让用户定义的变量值覆盖原有程序变量,可控制原程序逻辑。
<?php
highlight_file(‘index.php‘);
function waf($a){
foreach($a as $key => $value){
if(preg_match(‘/flag/i‘,$key)){
exit(‘are you a hacker‘);
}
}
}
foreach(array(‘_POST‘, ‘_GET‘, ‘_COOKIE‘) as $__R) {
if($$__R) {
foreach($$__R as $__k => $__v) {
if(isset($$__k) && $$__k == $__v) unset($$__k);
}
}
}
if($_POST) { waf($_POST);}
if($_GET) { waf($_GET); }
if($_COOKIE) { waf($_COOKIE);}
if($_POST) extract($_POST, EXTR_SKIP);
if($_GET) extract($_GET, EXTR_SKIP);
if(isset($_GET[‘flag‘])){
if($_GET[‘flag‘] === $_GET[‘daiker‘]){
exit(‘error‘);
}
if(md5($_GET[‘flag‘] ) == md5($_Ginclude($_GET[‘file‘]){
echo ‘flag={你猜猜}‘;
}
}
?>
??首先对一下代码进行分析
function waf($a){
foreach($a as $key => $value){
if(preg_match(‘/flag/i‘,$key)){
exit(‘are you a hacker‘);
}
}
}
??我们知道foreach是php遍历数组的一种方式,这里waf函数遍历$a里面的变量名和变量值,如果变量名中含有flag,则报错
foreach(array(‘_POST‘, ‘_GET‘, ‘_COOKIE‘) as $__R) {
if($$__R) {
foreach($$__R as $__k => $__v) {
if(isset($$__k) && $$__k == $__v) unset($$__k);
}
}
}
??将_POST,_GET,_COOKIE 中的值作为 $__R值 判断 是否存在以$R值为变量名的变量,如果有 继续遍历这个变量里的变量名和变量值,如果有里面的变量名存在而且变量名等于变量值就销毁变量$$,
。。这样说确实有点乱,但是后面这段foreach 和 熟悉的$$ 应该能想到是通过GET 进行传参。也就是说 $__k==$_GET[flag] ,因为后面要判断flag传参,所以这里只能是flag。 $$__k 是取 $_GET[flag]中的值作为变量名,
之后结合实战可能更好理解点吧
if($_POST) { waf($_POST);}
if($_GET) { waf($_GET); }
if($_COOKIE) { waf($_COOKIE);}
if($_POST) extract($_POST, EXTR_SKIP);
if($_GET) extract($_GET, EXTR_SKIP);
if(isset($_GET[‘flag‘])){
if($_GET[‘flag‘] === $_GET[‘daiker‘]){
exit(‘error‘);
}
if(md5($_GET[‘flag‘] ) == md5($_GET[‘daiker‘])){
echo ‘flag={你猜猜}‘;
}
}
??通过 if 判断 是否存在POST,GET,COOKIE 变量传参,如果存在 用waf去检测
然后再使用extract($_POST, EXTR_SKIP),extract($_GET, EXTR_SKIP)将变量写入符号表保存起来,而且使用到EXTR_SKIP关键字后不会覆盖之前的变量。
最后判断是否通过flag进行了传参,传了后,将$flag中的值和$daiker进行比较,相同则结束, 不相同 则 通过md5加密 进行比较,这里存在个php若类型,
我们可以通过两种md5加密后为0e开头的字符串进行绕过,比如QNKCDZO和s878926199a
原文:https://www.cnblogs.com/Dark1nt/p/14797128.html