easytrick
<?php
class trick{
public $trick1;
public $trick2;
public function __destruct()
{
$this->trick1 = (string)$this->trick1;
if(strlen($this->trick1) > 5 || strlen($this->trick2) > 5)
{
die("你太长了");
}
if($this->trick1 !== $this->trick2 && md5($this->trick1) === md5($this->trick2) && $this->trick1 != $this->trick2)
{
echo file_get_contents("/flag");
}
}
}
只有__destruct()函数,在函数被销毁时调用,两个WAF,长度限制和php的md5绕过。
在php中===为完全等于运算,不仅比较值,而且还比较值的类型,只有两者一致才为真。
需要满足三个要求:
trick1 !== trick2
md5(trick1) === md5(trick2)
trick1 != trick2
先来看看常见的绕过方法:
- md5加密后生成的字符串为"0e"开头,每个哈希值都解释为0。这里受到长度限制以及类型限制。
- md5([1,2,3]) == md5([4,5,6]) == NULL。这里存在strlen()函数,传入的的对象只能是字符串不能是数组。
- MD5碰撞。长度过长。
方法1 浮点数松散比较绕过
利用php浮点数特性,
- 最大相对误差为 1.11e-16。如1.1*1.1=1.2100000000000002。
- 作为md5字符串时忽略了剩下精度。
方法2 NAN(INF)类型比较绕过
参考了y1ng师傅的博客。
NAN和INF,分别为非数字和无穷大。
但是var_dump一下它们的数据类型却是double,那么在md5函数处理它们的时候,是将其直接转换为字符串”NAN”和字符串”INF”使用的,但是它们拥有特殊的性质,它们与任何数据类型(除了true)做强类型或弱类型比较均为false,甚至NAN==NAN都是false。
通过这个性质,可以令trick1=”NAN”,trick2=NAN。
Last modified 8mo ago