easyphp-wp

题目:

<?php
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;

$a = $_GET['a'];
$b = $_GET['b'];

if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
    if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
        $key1 = 1;
        }else{
            die("Emmm...再想想");
        }
    }else{
    die("Emmm...");
}

$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }
        $key2 = 1;
    }else{
        die("no hack");
    }
}else{
    die("no");
}

if($key1 && $key2){
    include "Hgfks.php";
    echo "You're right"."\\n";
    echo $flag;
}

?>

打开后进行审计 想拿到flag 就要让key1和key2 都为1 才能输出flag。

先看让key1变为1 的条件

**intval()**函数用于获取变量的整数值。

intval($a) > 6000000 && strlen($a) <= 3

a的位数还不能大于3位,intval是能识别科学计数法的

让a=1e9 intval就会把a认为1000000000 10的九次方

图片[1]-easyphp-wp-Drton1博客

让a=1e9就符合条件了。

再看b:

 '8b184b' === substr(md5($b),-6,6

要让b的md5加密值后五位等于’8b184b’;

这里用md5碰撞 说白了 就是 一个一个试:

图片[2]-easyphp-wp-Drton1博客

可能break php不识别 但是就是这个思路 得出来7597945

图片[3]-easyphp-wp-Drton1博客

让b=7597945就符合了。

这就符合让key1=1 的条件了

接下来要看看key2=1需要满足什么条件:

$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }
        $key2 = 1;
    }else{
        die("no hack");
    }
}else{
    die("no");
}

可以看到它接受的是json格式的数据

c={“m”:”20233X”,

“n”:[[1,2,3],0]}

!is_numeric(@$c["m"]) && $c["m"] > 2022

数据中 m键值 会被先判断是不是数字 如果是 就不能通过验证,然后还会跟2022去比较:

php中当一个其他数据类型和数值类型的数据比较大小时,会先将其他数据类型转换成数值类型,这里输入类似9999a数据也可绕过 j=9999a

利用这个机制 我们可以让 m这个键值等于一个9999a 他带字母a 就会被 is_numberic 认为不是一个数字型 绕过验证 然后跟2022比较时再自己转换为数值型。

所以我们让m的键值等于9999a

if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0]))

接下来他会判断 n这个键值是不是数组 且 这个数组里面的元素是不是2个

然后又判断n这个键值第一个元素是不是数组

那么我们很好绕过 让 “n”: [ [1,2] ,0] 就符合要求了

然后接下来这个判断很唬人

 $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }

一定要知道php中 == 跟 ===的区别

==是弱比较 什么意思呢

2==”2“ —> 真

2==” 2“ —>真

就是他不会去看类型 空格什么 只会比较数字

那么 0 跟 flase 在==情况下为真为假?

图片[4]-easyphp-wp-Drton1博客

可以看到为真

再来说说=== 强比较:

这个就是既比较数值 也并比较内容 都一样 才为真 像刚才上面那个例子:

2===”2“ —>假

2===“ 2”—>假

那么 0 跟 flase 在===情况下为真为假?

图片[5]-easyphp-wp-Drton1博客

可以看到为假

所以说:

 $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }

就是唬人用的 我们就算不满足 他的条件 他也都为假 不会触发die函数

于是c的构造就出来了:

c={“m”:”9999X”,”n”:[[1,2],0]}

图片[6]-easyphp-wp-Drton1博客

综上我们传参进去拿到flag。

cyberpeace{4b7a03079979b516201cb03d288e3354}

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论