攻防世界新手区 easyphp题解

前言

这个题目虽然是easyphp,但对我这中小白来说,一点都不easy啊。写不好的地方,大家多包涵包涵

正文部分

进入题目,首先就看到了代码,初步看了一下,大概就是要获得key1和key2才能拿到flag,

key1和key2又要通过传参a,b,c来获得

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

 先看第一部分

看不懂,只能一个一个的查了


$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...");
}
第一句if语句

intval():函数用于获取变量的整形值

isset():用来检测变量是否已设置并且为NULL

&&:逻辑与运算符,只有当两个操作数都为真是才计算为真,如果任何一个数为假,他的计算结果都为假

strlen():用来获取字符串长度,成功则返回字符串string长度;如果string为空。则返回0

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

这句代码的意思就是:变量a不能为空和整形变量要大于6000000,而且的字符长度小于等于3

首先想到的就是用科学计数法,写了一个简单的代码试了一下

防线当a=6e6是刚好等于6000000,所以a的值可以是1e7/8/9

第二句if语句

=== :PHP中的强等于,类型和大小都要相等

md5()函数:我的理解是将字符串转换成md5

substr(md5($b),-6,6):从md5($b)后6位开始,截取6个字符串

if(isset($b) && '8b184b' === substr(md5($b),-6,6)){

这句代码的意思是:变量的b的值不能为空,而且b的MD5值的后六位必须等于8b184b

我也是看了其他博主的方法,才找到b的值的。使用python进行爆破

运行结果为:53724

代码解读:

1.python采用hashlib这个标准库实现MD5加密解密。
2.i.encode(encoding='UTF-8')处,i要为字符串,因此要先转换整数i为字符串,并且将其转化为UTF-8编码形式。
3.hexdigest()该方法是将hash中的数据转换成数据,其中只包含十六进制的数字。

所以a=6e7&b=53724

在看第二部分

这一部分自己查都没查懂,最后只能看了其他大佬的解析才明白一点

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

count() :函数返回数组中元素的数目。

array()函数:用于创建数组

json_decode()函数:用于将json对象解码或转换为PHP对象

语法:mixed json_decode ($json_string [,$assoc = false [, $depth = 512 [, $options = 0 ]]])

$json_string:待解码的json字符串,必须是UTF-8编码数据

is_array()函数:用于检测变量是否是一个数组

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

array_search()函数:在数组中搜索某个建值,并返回对于的键名

:单个感叹号是取反的意思,也就是取当前结果的反面

@:是忽略错误提示,使错误不会显示在程序里,&是取地址,也可以说是地址引用(不确定准不准确奥)

第一句

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

这句话的意思是:数组c中一个m, m的值要大于2022

所以可以是:"m":"2023a"   

第二句

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

 这句话的意识是:变量c的值n是一个数组,并且n数组有两个值,并且c变量n值的第一个值为数组,此时我们可以找到c变量的格式:{'m':xx,'n':[[xx,xx..],xx]}

第三句

$d = array_search("DGGJ", $c["n"]);
$d === false?die("no..."):NULL;

这句话的意思:要求array_search搜索n中是否有”DGGJ”,有的话才能开启下一步

第四句

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

这里使用foreach循环搜索n中的值是否含有"DGGJ“,又要求没有的话才会是key的值为1

绕过:所以我们必须要绕过其中一个函数,array_search函数是可以绕过的,当函数将字符串与数字进行比较时,会将字符串强制转换为整形进行比较,”DGGJ“转换为整形就是0

所以c={"m":"2023a","n":[[0,2],0]}

最终构成payload:

a=6e7&b=53724&c={"m":"2023a","n":[[0,2],0]}

总结:

这个题目做了一下午,也看很多大佬的解析教程,确实学习到了不少只是。

这是我第一次写博客,写不好,大家多包包涵包涵。

我想这也算是对自己进步的一种的记录了吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值