前言
这个题目虽然是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]}
总结:
这个题目做了一下午,也看很多大佬的解析教程,确实学习到了不少只是。
这是我第一次写博客,写不好,大家多包包涵包涵。
我想这也算是对自己进步的一种的记录了吧