很久没学东西了,被很多事情弄的神志不清。

感觉自己好像沉太久了,还是该醒醒,今天写道php代码审计绕过题目

先看题目

先分层

第一层判断:if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3)

isset:检测变量是否设置 intval:获取变量的整数值 strlen:计算变量的长度

题问点在于:变量a要大于6000000,长度却不能超过三个字符;

考点是php中可以使用科学计数法来绕过,如1e9,用get方式传入,

构造payload:/?a=1e9,得到回显

第二层判断:if(isset($b) && ‘8b184b’ === substr(md5($b),-6,6))

substr:截取字符串并返回,例子

题问点:md5加密后的b,截取的六位等于”8b184b”

写脚本得到题目需要的值即可

得到值53724,构造payload:/?a=1e9&&?b=53724

然后进入第二部分

第二部分:$c=(array)json_decode(@$_GET[‘c’]);

分析:要求变量c进行json_decode,在php中该函数用于对 JSON 格式的字符串进行解码,转换为 PHP 变量,因此可以最后再来进行

继续分析,第一层:

if(is_array($c) && !is_numeric(@$c[“m”]) && $c[“m”] > 2022)

首先要求变量c为数组,同时要求c中m不能是数字且要大于2022

is_numeric:用于检测变量是否为数字或者字符串

查找博客:[CTF]php is_numeric绕过_ctf is_numeric()-CSDN博客

得知可以通过其他字符来绕过,如%00的空字符、’、,等字符;

php弱类型的特点也可以利用,在php中用数字和字符串进行比较时,会将字符串从第一个非数字处截断,将截断前的部分当作数字比较,而字符串数据类型本身不是数字,依此可以顺利绕过。

第二层;

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

这里是要求变量c中有n为数组,n有两个值且第一个值为数组

第三层;

        $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");
}

array_search:在数组中搜索某个键值,并返回对应的键名。

这里是搜索变量c中n需要有DGGJ才能才能保证d不为假,但是在之后又会遍历n,如果其中有DGGJ则终止程序,显然二者是矛盾的

可以利用函数接入到不符合的类型返回0的特点绕过,当array_search在数值型数组中查找DGGJ时,会先把字符串转换为数字,于是DGGJ变成了0,查找到后返回其键名,数组中0的键名依旧是0,而0===0;

因此构造c中m=9999a,n[[],0]再进行json_encode编码成json格式得到payload

payload:/?a=1e9&&b=53724&&c={“m”:”9999a”,”n”:[[],0]

得到flag

好久没写博客了,用期末考的名义摆烂了很久,但我觉得还是不能烂下去,学点什么总比整天没意义的混日子好

究其原因还是打猎打魔怔了、、、、、


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注