今天碰到这题,感觉有很多知识点,就决定记录一下
这里我用的是攻防世界的靶场
easyphp——攻防世界
题目分析
上来就分析php代码,那就逐行看一下,可以知道最终目的是要使key1和key2都是1
发现文末有一行Emmm...
,再根据上面代码推断即可知道是第一个if判断没有进入导致的
而要进入也很简单,先来看一下代码
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3)
可以看到a不能为空,同时要在字符数量小于等于3的情况下大于6000000,因此容易想到利用科学计数法。
构造第一个payload
a=6e9
接着看第二个if
md5推算
if(isset($b) && '8b184b' === substr(md5($b),-6,6))
可以看到第二个if需要利用md5解码,先去看一下8b184b
对应字符串。这里我们可以通过简单的Python脚本来解决这个哈希碰撞
import random
import hashlib
value = "8b184b"
while 1:
plainText = random.randint(10**11, 10**12 - 1)
plainText = str(plainText)
MD5 = hashlib.md5()
MD5.update(plainText.encode(encoding='utf-8'))
cipherText = MD5.hexdigest()
if cipherText[-6:]==value :
print("碰撞成功:")
print("密文为:"+cipherText)
print("明文为:"+plainText)
break
else:
print("碰撞中.....")
密文:842fc2485a1faa0681f78d3e098b184b
明文:792616362347
可以得到结果。但考虑到计算量比较大,所以对代码进行一些简化,只截取8b184b这部分进行判断,不做满位拓展
import hashlib
for i in range(1000000):
m2 = hashlib.md5()
m2.update(str(i).encode())
if m2.hexdigest()[-6:] == "8b184b":
print(i)
break
得到结果为53724,计算量明显缩小
只要将b等于明文即可
这里我主要想记录一下substr函数第2、3个参数的含义
substr()
到这里参数a和b已经可以成功使key1=1,接着继续看参数c
$c=(array)json_decode(@$_GET['c']);
这里需要使用json来写
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022)
第一个条件自然可以过,重点是第二、三个条件,c[m]要在不是数字的情况下大于2022,这里由于不清楚php具体版本,所以可以有两种思路
弱比较和is_numeric()函数漏洞
- 使用弱比较,这是PHP全版本的特性,具体使用如下
(来自:CTF—-PHP弱类型比较)
- 使用%00空字符在使其误判,但由于是漏洞而不是特性,因此还没证实在各个版本中均有效
可以参考:php intval()函数漏洞,is_numeric() 漏洞,绕过回文判断
这里我用第一种思路
接着继续看到下一句if
if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0]))
这句就很明显了,首先c[n]必须**也是数组,并且c[n]这个数组的长度得是2,其中c[n]的首项cn也**是数组,因此这里就有三个数组的嵌套。
到这里为止,可以大概知道c的payload是c={“m”:“2023a”,“n”:[[1],0]}
我们继续往下看
$d = array_search("DGGJ", $c["n"]);
$d === false?die("no..."):NULL;
可以看到他要求我们的c[n]必须拥有DGGJ,才不会执行die
可是继续看下去,发现还有这句
foreach($c["n"] as $key=>$val){
$val==="DGGJ"?die("no......"):NULL;
}
函数foreach()
的作用是遍历数组,可以看到这里他要求必须要有DGGJ,因此与上面那句是矛盾的
有什么方法绕过呢?这里需要一点php赋值与判断独有的前置知识,也就是我们上面讲到的弱比较,要是不明白可以到上面去看一下那篇博客
array_search()特性
这里因为array_search()
函数内部使用的判断方法就是类似的类型转换(下图为官方介绍),因此可以将c[n]均设为0或cn为null,cn为0
结合上面的a和b便可以构造出最后的payload
?a=6e7&b=53724&c={“m”:“2023a”,“n”:[[],0]}