Log4j2再现高危RCE:FilteredObjectInputStream白名单绕过漏洞解析

导语:2026年8月24日,安全研究员公开披露了Apache Log4j2一个尚未修复的远程代码执行(RCE)漏洞。该漏洞影响2.11.0至2.26.1所有版本,攻击者可通过 java.rmi.MarshalledObject 绕过 FilteredObjectInputStream 反序列化白名单,实现静默的任意命令执行。目前尚无CVE编号,也尚无官方补丁——距离Log4Shell惊天漏洞五年之后,Log4j2再次敲响警钟。


一、漏洞概述

8月24日,U-Sec(无界安全)团队在Apache官方仓库提交了编号为#4255的安全问题,公开披露了Log4j2的 FilteredObjectInputStream(过滤对象输入流,简称FOIS)白名单绕过漏洞。

核心信息速览:

项目详情
漏洞类型不安全反序列化(CWE-502)导致RCE
影响版本Log4j 2.11.0 ~ 2.26.1(所有版本)
CVE编号尚未分配
补丁状态未修复(issue处于OPEN/等待维护者状态)
攻击前提存在基于FOIS的反序列化日志接收端,且classpath含可利用gadget
触发方式单次未认证TCP写入序列化LogEvent对象

这不是又一个”日志字符串触发”的Log4Shell翻版。它需要原始序列化字节到达socket桥接端,属于应用条件性RCE,而非通用型Log4j漏洞。


二、漏洞原理分析

2.1 白名单为何形同虚设

Log4j的 FilteredObjectInputStream 是一个基于 resolveClass() 的反序列化白名单机制。它的白名单中包含了 java.rmi.MarshalledObject

问题就出在这里。MarshalledObject 将载荷存储为一个不透明的 byte[],而 MarshalledObject.get() 方法会在一个全新且无过滤的 ObjectInputStream 上对这段字节进行反序列化——白名单永远不会检查这个内部对象图。

Log4j反序列化攻击流程图

2.2 Log4j自身的自动触发

更致命的是,Log4j会自己触发这个流程。从2.8版本起,Log4jLogEvent$LogEventProxy(LogEvent的序列化线格式)将事件消息封装在 MarshalledObject 中,并在反序列化过程中自动调用 .get() 方法(readResolve() → message())。

这意味着任何通过FOIS读取序列化LogEvent的应用,都会对攻击者提供的字节执行无过滤反序列化。而由于 message() 会吞掉抛出的异常并回退到 SimpleMessage,接收端只会记录一条看起来人畜无害的事件,然后继续运行——攻击完全静默

2.3 关键缺陷点定位

位置缺陷
log4j-api/util/internal/SerializationUtil.java允许列表包含 java.rmi.MarshalledObject
log4j-api/util/FilteredObjectInputStream.java仅重写 resolveClass(),看不到 objBytes 载荷
log4j-core/impl/Log4jLogEvent.javaLogEventProxy.marshalledMessageMarshalledObject<Message>
log4j-core/impl/Log4jLogEvent.javamessage() 调用 marshalledMessage.get()(无过滤)且吞掉所有异常

三、攻击路径与PoC

攻击者只需构造一个序列化的LogEvent对象,通过未认证的TCP连接发送给基于FOIS的日志接收端即可。攻击路径如下:

构建LogEvent
  → Log4j的writeReplace()/writeObject()将Message封装进MarshalledObject
  → gadget隐藏在MarshalledObject不透明的byte[]中
  → 接收端readResolve() → message() → MarshalledObject.get()
  → 打开全新无过滤流 → gadget触发 → Runtime.exec()

已有安全研究员dinosn发布了完整的复现环境,是一个基于Docker的端到端实验环境,针对Log4j 2.26.1 / JDK 17,使用纯 CommonsCollections6 gadget链拼接进 MarshalledObjectobjBytes,因此受害端无需任何攻击者自定义类即可触发RCE。

3.1 关键验证场景

场景受害classpathjdk.serialFilter结果
顶层发送被禁gadget+ gadget拒绝(FOIS白名单拦截)
gadget封装进LogEvent+ gadgetRCE(自动触发)
顶层原始CC6log4j + cc-3.2.1拒绝
CC6拼接进MarshalledObjectlog4j + cc-3.2.1RCE(无需攻击者类)
上述载荷log4j + cc-3.2.1!java.rmi.MarshalledObject拒绝(缓解生效)
上述载荷log4j + cc-3.2.2静默(3.2.2禁用不安全functor反序列化)

四、利用工具与测试代码下载

为方便安全研究人员复现与分析该漏洞,以下是相关资源:

4.1 复现实验环境(Docker Lab)

  • 项目地址:https://github.com/dinosn/log4j-4255
  • 克隆命令git clone https://github.com/dinosn/log4j-4255.git
  • 运行方式./run.shmake run(仅需Docker,自动拉取JDK 17镜像)
  • 组成
    • src/victim/Receiver.java:FOIS日志接收端(模拟ObjectInputStreamLogEventBridge)
    • src/attacker/Attacker.java:载荷构建器(含对照组、PoC-1、PoC-2 CC6字节拼接)
    • src/attacker/EvilMessage.java:PoC-1自包含gadget
    • docs/RESULTS.md:证据矩阵与分析

4.2 官方问题跟踪

  • Apache Issue #4255:https://github.com/apache/logging-log4j2/issues/4255
  • 安全讨论 #4168(Log4j 2.x反序列化加固):https://github.com/apache/logging-log4j2/discussions/4168

⚠️ 法律声明:以上工具与代码仅供安全研究与漏洞复现使用,请勿对未授权系统发起测试。利用PoC复现前请确保已获得目标系统所有者的明确授权。


五、影响评估

5.1 不是Log4Shell 2.0

知名研究员Giuseppe(N3mes1s)已明确表示:”这不是下一个Log4Shell。” 关键区别在于攻击前提:

  • Log4Shell:仅需在日志中记录一段字符串即可触发(远程无前置条件)
  • 本次漏洞:必须有一个暴露的、基于FOIS的反序列化日志接收端,且攻击者需能与其建立TCP连接(应用条件性)

5.2 实际影响面

Log4j核心自带的序列化socket服务在2.8.2之后已移出log4j-core(2.9.0起不再存在),因此现代接收端多为应用或示例代码自建。普通Log4j部署不会运行此类接收端。

但危险在于:Elasticsearch等依赖Log4j的组件已经在官方论坛被问询影响范围。任何通过Java序列化传输日志、且暴露在不可信网络的应用,都是潜在目标。


六、防御与缓解建议

由于官方补丁尚未发布,当前可采取的临时缓解措施如下:

  1. 结构级修复(首选):消除基于Java序列化的日志传输,改用JSON或RFC 5424格式,并通过认证的TLS通道传输。
  2. JVM过滤(有效但非透明):在接收端JVM设置 -Djdk.serialFilter='!java.rmi.MarshalledObject'。注意这会同时阻断合法的序列化LogEventProxy对象(它们也使用MarshalledObject)。
  3. 清理gadget依赖:移除或升级易受攻击的依赖库。例如 commons-collections 3.2.1可被利用,而3.2.2已禁用不安全的functor反序列化。
  4. 暴露面收敛:不要在不可信网络上暴露基于FOIS的序列化日志接收端。
  5. 等待上游修复:官方建议的修复方案是——将 MarshalledObject 从白名单中移除,并将封装的message迁移到Log4j过滤后的 writeWrappedObject/readWrappedObject

七、总结

Log4j2在Log4Shell余波五年之后,再次暴露出反序列化链路的深层隐患。本次漏洞的核心教训是:任何”白名单”过滤机制,只要允许了能在内部开启全新无过滤流的对象(如 MarshalledObject),就等于给攻击者留了一扇后门。

攻击者不需要完美的原生读写原语,不需要绕过复杂的沙箱——只需要一个”看起来无害”的对象,让框架自己把恶意载荷送进无过滤的反序列化流。这提醒所有安全人员:对序列化边界的信任,必须建立在”每一层都不信任”的原则之上。

在官方补丁发布前,建议所有使用Log4j 2.11.0至2.26.1、且存在日志序列化传输场景的企业,立即按上述缓解措施加固,并持续关注Apache官方仓库的修复进展。


参考资料

  1. Apache Log4j2 Issue #4255:https://github.com/apache/logging-log4j2/issues/4255
  2. dinosn/log4j-4255 复现环境:https://github.com/dinosn/log4j-4255
  3. SecurityOnline 公开披露报告
  4. Apache Log4j CWE-502 FAQ:https://logging.apache.org/security/faq.html

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容