反序列化漏洞

序列化/反序列化

  • 序列化:将对象转为字节流,目的是方便对象在内存、文件、数据库或者网络之间的传递

  • 反序列化:序列化的逆过程,即将字节流转为对象的过程

序列化技术的用途

• 经由电信线路传输资料(通信) • 存储资料(存在数据库或硬盘) • 远程程序调用 • 检测随时间资料的变动

漏洞原理

  • 原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果

  • 反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通

漏洞危害

  • 不安全的反序列化,主要造成的危害是远程代码执行

  • 如果无法远程代码执行,也可能导致权限提升、任意文件读取、拒绝服务攻击等

防御方式

  • 应该尽量避免用户输入反序列化的参数

  • 如果确实需要对不受信任的数据源进行反序列化,需要确保数据未被篡改,比如使用数字签名来检查数据的完整性

  • 严格控制反序列化相关函数的参数,坚持用户所输入的信息都是不可靠的原则

  • 对于反序列化后的变量内容进行检查,以确定内容没有被污染

  • 做好代码审计相关工作,提高开发人员的安全意识

PHP反序列化

  • PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果

  • 相关函数:serialize()unserialize()

对象转为字符序列

常见的表示类型的字符

访问控制符:public/protected/private

魔术方法

魔术方法
作用

__construct()

当一个对象创建时被调用

__destruct()

当一个对象销毁时被调用

__toString()

当一个对象当作一个字符串使用时调用

__sleep()

当对象被序列化之前调用

__wakeup()

当对象被反序列化之后被调用

__call()

当对象调用某个不存在的方法时调用

__get()

当读取一个不存在的属性值时调用

__set()

当给一个不存在的属性复制时调用

__clone()

当克隆对象时调用

__isset()

当检测一个对象的属性是否存在时调用

__unset()

删除一个对象时调用

__set_state()

调用var_export时调用

绕过方式

  • 属性 个数大于实际个数的时候,会绕过 __wakeup 方法

  • protected 类型属性要使用 \00 代替空,并且小 s 变大 S

payload

Typecho反序列化

Typecho是一个简单,轻巧的博客程序。基于PHP,使用多种数据库(Mysql,PostgreSQL,SQLite)储存数据。在GPL Version 2许可证下发行,是一个开源的程序,Typecho漏洞发生在网站的install.php文件

利用链

JAVA反序列化

  • Java框架:Spring MVC、MyBatis、Dubbo、Maven、RabbitMQ、Redis、Shiro、Log4J

  • Java中间件:Apache、Tomcat、Struts、WebLogic、JBoss

• Java序列化就是指把Java对象转换为字节序列的过程,Java反序列化就是指把字节序列恢复为Java对象的过程 • 序列化的作用:在传递和保存对象时,保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中 • 反序列化的作用:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象

用途

• 将对象转为字节流存储到硬盘上,当JVM停机的话,字节流还会在硬盘上默默等待,等待下一次JVM的启动,把序列化的对象,通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)。 • 序列化成字节流形式的对象可以进行网络传输(二进制形式),方便了网络传输 • 通过序列化可以在进程间传递对象

• 序列化:Java序列化是指把java的对象转化为字节序列的一个过程,便于储存 • ObjectOutputStream类的writeObject()方法可以实现序列化 • 反序列化:就是把字符序列恢复为java对象的的过程 • ObjectInputStream类的readObject()用于反序列化 • 序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。

序列化技术对比

维度
Java序列化
JSON
Thrift
ProtoBuf
Avro

跨语言

协议可读性

Java代码,无协议

好,易于理解

较好

较好

较好

数据类型

任意对象

任意类型,不支持union

任意类型,支持union

任意类型,支持union

任意类型,支持union

开发成本

直接使用

引入JSON库

安装Thrift工具,引入Thrift库

安装protoc工具,引入ProtoBuf库

引入Avro库

Jboss简介

• Jboss是一个基于J2EE的开放源代码的应用服务器。 JBoss代码遵循LGPL许可,可以在任何商业应用中免费使用。JBoss是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3的规范。但JBoss核心服务不包括支持servlet/JSP的WEB容器,一般与Tomcat或Jetty绑定使用。 • JBoss应用服务器还具有许多优秀的特质。JBoss运行后后台管理界面 • 其一,将具有革命性的JMX微内核服务作为其总线结构; • 其二,本身就是面向服务架构(Service-Oriented Architecture); • 其三,具有统一的类装载器,从而能够实现应用的热部署和热卸载能力。

Last updated