[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解

news2024/11/27 5:20:39

[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解

    • _wakeup()及php序列化反序列化
      • 序列化字符串结构分析
      • _wakeup()的利用
    • 解题思路
      • 伪属性数量绕过
    • 解题姿势
    • 总结

在这里插入图片描述

_wakeup()及php序列化反序列化

序列化是指将数据结构或对象转换为可传输或可存储的格式的过程。这通常需要将数据转换为字节流或其他形式的编码格式,以便能够在不同的系统和应用程序之间进行传输或存储。

在 PHP 中,可以使用 serialize() 函数将对象序列化为字符串,然后保存到文件或传输到其他应用程序中。

序列化后的数据包含了对象的属性、方法和类型等信息,但没有对象的实例本身

反序列化则是将序列化后的数据重新转换为对象、数据结构或变量的过程,以便在程序中进行操作或处理。

在 PHP 中,可以使用 unserialize() 函数将序列化后的字符串还原为原始的对象或数据,然后进行处理。

反序列化过程需要按照序列化时的格式和规则进行解析和处理,以确保数据的完整性和正确性。


这段代码涉及了 PHP 中的魔术方法 __wakeup() 和对象序列化的概念。其中 __wakeup() 在反序列化对象时自动调用,用于初始化对象的属性等操作。

对于上述代码中的 xctf 类,它有一个 $flag 属性,以及一个 __wakeup() 方法。当一个 xctf 对象被序列化并存储为字符串后,如果再次反序列化该字符串并尝试重建相应的对象时,PHP 就会自动调用该对象的 __wakeup() 方法。


因此,对于上述代码而言,如果访问一个类似 ?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";} 的 URL 地址,该地址会将序列化后的 xctf 对象(即code.php?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";})传递给 PHP 引擎处理。如果该对象被成功反序列化,那么 __wakeup() 方法将会被自动调用,程序将会直接终止执行并输出 bad requests

序列化字符串结构分析

O:4:"xctf":1:{s:4:"flag";s:3:"111";} 是一个序列化后的字符串,表示一个名为 xctf 的对象,该对象有一个属性 flag,属性值为 111。它的具体结构如下:

  • O:表示被序列化的是一个对象
  • 4:表示对象名 xctf 有4个字符
  • "xctf":表示对象的名称为 xctf
  • 1:表示该对象只有一个属性
  • {}:表示该对象的属性列表为空
  • s:表示属性类型为字符串
  • 4:表示属性名 flag 有4个字符
  • "flag":表示属性名为 flag
  • s:表示属性类型为字符串
  • 3:表示属性值 111 有3个字符
  • "111":表示属性值为 111

_wakeup()的利用

如果 __wakeup() 方法不终止程序执行,那么在将序列化字符串反序列化为对象时,该方法会自动被调用,并执行其中的代码。在上述 xctf 类中,我们可以在 __wakeup() 方法中编写一些初始化对象属性等操作,使得wakeup函数中的对象经反序列化后能够正确运行

如果将 __wakeup() 方法修改为如下代码:

public function __wakeup(){
    $this->flag = '222';
}

则在将序列化字符串 O:4:"xctf":1:{s:4:"flag";s:3:"111";} 反序列化为对象时,该对象的 $flag 属性值会被重置为 222。具体代码如下:

<?php

class xctf{
    public $flag = '111';
    public function __wakeup(){
        $this->flag = '222';
    }
}

$serializedObj = 'O:4:"xctf":1:{s:4:"flag";s:3:"111";}'; // 序列化后的字符串

$obj = unserialize($serializedObj); // 反序列化

var_dump($obj); // 输出反序列化后的对象

运行上述代码后,输出结果如下:

object(xctf)#1 (1) {
  ["flag"]=>
  string(3) "222"
}

解题思路

由于反序列化时会自动调用_wakeup()函数,导致程序退出。
故可通过增大序列化字符串中表示对象属性个数的值,使其大于真实值,以此绕过_wakeup函数,(即伪属性绕过),从而实现程序正常运行。

伪属性数量绕过

假设有一个名为 Test 的 PHP 类,该类包含两个属性 $a$b,并且定义了 __wakeup() 方法。如果要绕过 __wakeup() 方法,可以将表示对象属性数量的值设定为大于 2 的值,如下所示:

class Test {
    private $a;
    private $b;
    
    public function __wakeup() {
        echo "Execute wakeup method";
    }
}

$obj = new Test();
$obj->a = "aaa";
$obj->b = "bbb";

$serializedObj = serialize($obj); // 将对象序列化为字符串并保存
echo $serializedObj . "\n"; // 输出序列化后的字符串

// 将表示属性数量的值从 2 改成 3 并重新进行反序列化
$modifiedSerializedObj = str_replace("2", "3", $serializedObj);
$unserializedObj = unserialize($modifiedSerializedObj);
echo $unserializedObj->a . "\n"; // 正常输出 "aaa"
echo $unserializedObj->b . "\n"; // 正常输出 "bbb"

在上述代码中,首先创建一个名为 Test 的类,并在其中定义 __wakeup() 方法。在 __wakeup() 方法中,简单地输出了一条日志信息,表示该方法被正常执行。接着,创建一个 Test 对象 $obj,其中包含两个属性 $a$b

$obj 对象序列化为字符串,并输出该字符串的内容。再将该字符串中表示对象属性数量的值 2 修改为 3,并将修改后的字符串传入 unserialize() 函数进行反序列化。

由于修改后的字符串中的属性数量大于实际属性数量,因此在反序列化时不会触发 __wakeup() 方法。当我们访问反序列化后的对象中的属性 $a$b 时,可以正常输出它们的值(即 "aaa""bbb"

若字符串中的属性数量等于实际属性数量,则不会输出aaa及bbb,仅输出日志信息

解题姿势

  1. 将对象序列化
    O:4:"xctf":1:{s:4:"flag";s:3:"111";}

  2. 增加字符串中对象属性数量
    O:4:"xctf":2:{s:4:"flag";s:3:"111";}

  3. 构造GET传参 /?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}

回显如下,反序列化时成功绕过_wakeup函数

在这里插入图片描述


总结

以上为[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解,分享序列化反序列化相关知识,读者可躬身实践。
我是秋说,我们下次见。

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

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

相关文章

14.Kafka系列之K8S部署集群

1. 部署方式选择 基于Kafka3.X后的集群搭建方式主要分为两种&#xff0c;一种是基于Zookeeper管理方式&#xff0c;一种是基于KRaft模式&#xff0c;本文主要介绍Kafka-KRaft集群模式搭建 纠正文章1.Kafka系列之K8S部署单节点中基于Zookeeper方式的部署方式错误&#xff0c;其…

Godot引擎 4.0 文档 - 入门介绍 - Godot设计理念

本文为Google Translate英译中结果&#xff0c;DrGraph在此基础上加了一些校正。英文原版页面&#xff1a; Godots design philosophy — Godot Engine (stable) documentation in English Godot设计理念 既然你已经了解了&#xff0c;让我们来谈谈 Godot 的设计。 每个游戏…

(转载)MATLAB智能算法30个案例分析(1)——遗传算法工具箱

以下内容大部分来源于《MATLAB智能算法30个案例分析》&#xff0c;仅为学习交流所用。 1理论基础 1.1遗传算法概述 遗传算法(genetic algorithm,GA)是一种进化算法,其基本原理是仿效生物界中的“物竞天择、适者生存”的演化法则。遗传算法是把问题参数编码为染色体,再利用迭代…

第11届蓝桥杯Scratch选拔赛真题集锦

目录 一、编程题 第11届蓝桥杯Scratch选拔赛真题集锦 一、编程题 第 1 题 问答题 马克思的手稿 题目说明 背景信息: 马克思手稿中有一道趣味数学问题: 有30个人&#xff0c;其中有男人、女人和小孩。在一家饭馆吃饭共花了50先令;每个男人花了3先令&#xff0c;每个女人花了…

draw.io如何绘制带箭头的弧线

好长时间没有写draw.io相关的技巧了。今天再补充一个小技巧。 如何绘制像下图中蓝色的带箭头的弧线&#xff1f; 本来以为这个问题应该很简单&#xff0c;但是在仔细研究了很久之后我发现这个问题并没有想像得那么容易。 众所周知&#xff0c;draw.io中带箭头的线叫作“connect…

软件工程 | 期末复习习题

一、软件工程概述 1、选择 软件有无可行性和不可控性 软件工程是一门工程性学科 软件生存周期常见模型&#xff1a;螺旋模型、增量模型、瀑布模型、原型模型、融合模型、快速应用开发模型、敏捷模型 软件生存周期中时间最长的阶段是维护阶段 瀑布模型是一种软件生存周期模…

微搭低代码实现aad的sso

微搭低代码平台是一种可帮助您快速构建和部署应用程序的工具&#xff0c;而无需手动编写大量代码。要在微搭低代码平台上实现Azure Active Directory&#xff08;AAD&#xff09;的单点登录&#xff08;SSO&#xff09;&#xff0c;您需要遵循以下步骤&#xff1a; 注册Azure …

SpringBoot整合Mybatis(3000字)

SpringBoot整合Mybatis 文章目录 SpringBoot整合Mybatis依赖导入配置信息(application.yml)代码分层数据库(建库建表语句)各层代码enity:dao:service:controller: 测试 Mybatis分页查询和模糊查询分页查询:测试: 模糊查询:测试: Mybatis的分布查询多对一:测试:一对多: Mybatis的…

邮箱营销不再难:如何提高邮件的到达率和打开率?

在数字时代&#xff0c;电子邮件是企业与客户以及潜在客户沟通的重要渠道&#xff0c;是企业培养客户的有效方式之一。然而&#xff0c;由于每个人每天也要收到大量的垃圾邮件&#xff0c;所以企业必须确保在正确的时间将邮件传递给正确的人。在这篇文章中&#xff0c;小编将探…

BEVDet 论文学习

1. 解决了什么问题&#xff1f; 自动驾驶系统感知周围的环境再进行决策&#xff0c;极具挑战。基于视觉的自动驾驶系统对准确性和效率的要求很严格&#xff0c;人们会采用不同的范式来解决 3D 检测和分割任务。对于多相机 3D 目标检测&#xff0c;image-view-based 方法如 FCO…

缓存更新策略

缓存更新策略 内存淘汰超时剔除主动更新说明利用Redis的内存淘汰机制&#xff0c;不用自己维护&#xff0c;当内存不足时会自动淘汰部分数据。下次查询时更新缓存。给缓存数据添加TTL(过期时间)&#xff0c;到期后自动删除缓存。下次查询时更新缓存。编写业务逻辑&#xff0c;…

CSAPP Lab4- PerfLab

代码优化 typedef struct { unsigned short red; /* R value */ unsigned short green; /* G value */ unsigned short blue; /* B value */ } pixel图像用一维数组表示&#xff0c;第&#xff08;i,j&#xff09;个像素表示为I[RIDX(i,j,n)]&#xff0c;n为图像的维数 #def…

Datacom-HCIE 02(10月26日更新)--含解析

单选题 1.[试题编号&#xff1a;189785] &#xff08;单选题&#xff09;如图所示&#xff0c;VTEP1上在BD20域内开启了ARP广播抑制功能&#xff0c;并且VTEP1通过 BGP EVPN路由学习到了PC2的ARP信息&#xff0c;则PC1发送的针对PC2的ARP请求&#xff0c;VIEP1在转发给VIEP2时…

sqli-labs Less-11,12

less-11(基于错误的POST型单引号字符型注入) sqlmap 1.使用bp抓包 2.保存为1.txt在本地&#xff0c;使用sqlmap查询数据库 sqlmap.py -r "C:\Users\wy199\Desktop\1.txt" --dbs 3.查询当前数据库的所有表 sqlmap.py -r "C:\Users\wy199\Desktop\1.txt"…

正点原子ALPHA开发板核心资源分析

目录 正点原子ALPHA开发板核心资源分析I.MX6ULL实物图对比SOC 主控芯片&#xff08;MCIMX6Y2CVM08AB&#xff09;NAND FLASHEMMCDDR3L 正点原子ALPHA开发板核心资源分析 I.MX6ULL实物图对比 I.MX6ULL NAND BTB 接口核心板资源图与 I.MX6ULL EMMC BTB 接口核心板资源图如上图&a…

安装ElasticSearch之前的准备工作jdk的安装

一.windows 下载jdk的软件 (1).进入jdk1.8官网 (2).根据电脑是32位还是64位按需下载 (3).点击下载之后就会跳转到Oracle账号登录界面 没有 Oracle账号的注册一下就可以了 下载好的jdk如下: 双击下一步下一步安装jdk 默认安装就可以了 配置环境变量 (1).电脑左下方设置选项 (2).…

UFT软件的安装与注意事项

安装包下载 UFT软件的安装包网上也有许多&#xff0c;这里我分享下我使用的--->UFT安装包 下载完成解压后进行安装。 要注意关闭杀毒软件&#xff0c;否则安装过程中某些组件可能会安装不上。 部分电脑在安装过程中出现以下提示&#xff0c;可以点击确定 然后我们查看桌面上…

学习open62541 --- [77] 修改String类型变量的注意点

对于String类型的节点&#xff0c;其值的类型是UA_String&#xff0c;在这篇文章中我们解释了UA_String的生成方法。 当我们修改String类型节点的值时&#xff0c;会事先准备一个UA_String变量&#xff0c;这时就会遇到一个选择&#xff1a;是否需要动态分配内存&#xff0c;即…

一种基于数值的横向相互作用

( A, B )---144*30*2---( 1, 0 )( 0, 1 ) 让网络的输入有144个节点&#xff0c;训练集AB各由12张二值化的图片组成&#xff0c;让A中每行有1个1&#xff0c;B中全是0&#xff0c;排列组合A &#xff0c;统计迭代次数的顺序。 前面实验已经表明对于A中每行只有1个1&#xff0c;…

虚幻or现实?堆区、栈区真实存在吗?是操作系统在骗你罢了...

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f427;引例 &#x1f426;进程地址空间&#x1f426;虚拟地址与物理内存的联系&#x1f514;回答引例中的问题&#x1f513;写时拷贝 &#x1f426;虚拟地址存在的意义&#x1f513;malloc的本质 &#x1f490;专栏…