反序列化初探
type
status
date
slug
tags
summary
category
icon
password
概念
序列化:把对象转换为字节序列的过程,即把对象转换为可以存储或传输的数据的过程。例如将内存中的对象转换为二进制数据流或文件,在网络传输过程中,可以是字节或是XML等格式。反序列化:把字节序列恢复为对象的过程,即把可以存储或传输的数据转换为对象的过程。例如将二进制数据流或文件加载到内存中还原为对象。
漏洞成因
在身份验证,文件读写,数据传输等功能处,在未对反序列化接口做访问控制,未对序列化数据做加密和签名,加密密钥使用硬编码(如Shiro 1.2.4),使用不安全的反序列化框架库(如Fastjson 1.2.24)或函数的情况下,由于序列化数据可被用户控制,攻击者可以精心构造恶意的序列化数据(执行特定代码或命令的数据)传递给应用程序,在应用程序反序列化对象时执行攻击者构造的恶意代码,达到攻击者的目的。
漏洞可能出现的位置
1.解析认证token、session的位置
2.将序列化的对象存储到磁盘文件或存入数据库后反序列化时的位置,如读取json文件,xml文件等
3.将对象序列化后在网络中传输,如传输json数据,xml数据等
4.参数传递给程序
5.使用RMI协议,被广泛使用的RMI协议完全基于序列化
6.使用了不安全的框架或基础类库,如JMX 、Fastjson和Jackson等
7.定义协议用来接收与发送原始的java对象
询问了web手相关事宜,反序列化大概考点是python、php、java三种语言
在Python和PHP中,一般通过构造一个包含魔术方法(在发生特定事件或场景时被自动调用的函数,通常是构造函数或析构函数)的类,然后在魔术方法中调用命令执行或代码执行函数,接着实例化这个类的一个对象并将该对象序列化后传递给程序,当程序反序列化该对象时触发魔术方法从而执行命令或代码。
在Java中没有魔术方法,但是有反射(reflection)机制:在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法,这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。一般利用反射机制来构造一个执行命令的对象或直接调用一个具有命令执行或代码执行功能的方法实现任意代码执行。
python:pickle模块
php:serialize函数
php
php class序列化后:
public:属性被序列化的时候属性值会变成
属性名
protected:属性被序列化的时候属性值会变成
\\x00*\\x00属性名
private:属性被序列化的时候属性值会变成
\\x00类名\\x00属性名
php魔术方法:
serialize() 函数会检查类中是否存在一个魔术方法。如果存在,该方法会先被调用,然后才执行序列化操作。
从序列化到反序列化这几个函数的执行过程是:
_sleep
方法在一个对象被序列化时调用,_wakeup
方法在一个对象被反序列化时调用__tostring()触发时机:
PHP序列化需注意以下几点:
1、序列化只序列属性,不序列方法 2、因为序列化不序列方法,所以反序列化之后如果想正常使用这个对象的话我们必须要依托这个类要在当前作用域存在的条件 3、我们能控制的只有类的属性,攻击就是寻找合适能被控制的属性,利用作用域本身存在的方法,基于属性发动攻击
4、PHP对象是存放在内存的堆空间段上的,PHP文件在执行结束的时候会将对象销毁。
CVE-2016-7124
CVE-2016-7124:当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
java反序列化
Java中通常使用
Java.io.ObjectOutputStream
类中的writeObject
方法进行序列化,java.io.ObjectInputStream
类中的readObject
方法进行反序列化。使用下面代码将字符串进行序列化和反序列化:程序执行后生成a.ser文件
以十六进制查看a.ser文件内容,如图:
ac ed 00 05
是java序列化内容的特征,如果经过base64编码,那么相对应的是rO0AB
:一个Java类的对象要想序列化成功,必须满足两个条件:
1.该类必须实现
java.io.Serializable
接口。2.该类的所有属性必须是可序列化的,如果有一个属性不是可序列化的,则该属性必须注明是短暂的。
java反序列化漏洞成因
暴露或间接暴露反序列化 API ,导致用户可以操作传入数据,攻击者可以精心构造反序列化对象并执行恶意代码
反序列化时会调用readObject()函数,如果重写了readObject函数,并且里面含有恶意代码,那么在反序列化时调用这个函数就会直接执行恶意代码。
这里定义了一个Myobject类并继承了Serializable接口,并且重写了readObject方法。在反序列化时会执行readObject方法。在readObject()方法中写入了Runtime.getRuntime().exec("calc.exe"),在反序列化时就会执行相应的命令。
这么看起来原理挺简单的,不过实际上就没有这种运气了,都得靠自己构造链子,不过这里先不探讨了,这里只是入个门…
这篇打算来看看,用工具比较多:CTFSHOW web入门 java反序列化篇(更新中)_ctfshow java反序列化-CSDN博客
参考:
上一篇
车UDS诊断协议学习
下一篇
shiro安全
Loading...