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 updated