# easytrick

```php
<?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中===为完全等于运算，不仅比较**值**，而且还比较值的**类型**，只有**两者一致**才为真。

需要满足三个要求：

```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。
