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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook-88.gitbook.io/ctf-writeup/2020/2020-ciscn/easytrick.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
