WriteUp3

Posted by Distiny on October 9, 2022

easyphp

<?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;
}

?> 

代码审计的题目,相当于学习一下php吧

以get方式传入了a,b,c三个值,大概看过去就是key1和key2都为ture时,则返回flag,然后依次看代码即可。

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

第一部分是两个if语句,分别限制了a和b

intval($a) > 6000000 a的整数值大于6000000

strlen($a) <= 3 a的字符长度小于等于3

利用科学计数法即可实现$a=1e9

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

要求b的md5值后五位为8b184b,只能写个脚本碰撞一下试试。

<?php
$flag = 0;
for ($b=0; $b <100000 ; $b++) { 
    if('8b184b' === substr(md5($b),-6,6))
        {
            echo $b;
            break;
        }
}
echo "get";
?>

得到b是53724

$c=(array)json_decode(@$_GET['c']);
# json_decode()用于接受一个 JSON 编码的字符串并且把它转换为 PHP 变量
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
#is_numeric用于检测变量是否为数字或数字字符串
#is_array用于检测变量是否为数组
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        #array_search用于在数组中搜索给定的值,如果成功则返回首个相应的键名,否则返回false
        $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");
}

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

  • c是一个数组
  • c的m键值不是数组
  • c的m键值>2022

​ ——只需要c={"m":"2023a"},因为2023a和一个整数比较时,它会转换为2023。

‘123a’和一个整数作比较时,它会转换成123;

‘a123’和整数作比较时,由于第一个位置是a,非整数,php则规定其值为0,即变成了0和123比较

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

  • c的n键值是数组
  • c的n键值的数组大小为2
  • c的n键值的数组的第一个值为数组

​ ——c={"m":"2023a","n":[[1,2],1]}

之后是说查找n键中可以搜索到”DGGJ”,而且n键中又不能有值为”DGGJ”,前后矛盾,需要想办法破局…

解决的方法是array_search在寻找时使用的对比方法和比较大小的原则一样,如果”DGGJ”和整数比较,则会将”DGGJ”转换为0,所以将n数组的第二个值改成0,即可绕果。

​ ——c={"m":"2023a","n":[[1,2],0]}

综上所述a=1e9&&b=53724&&c={“m”:”2023a”,”n”:[[1,2],0]}