导语: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 上对这段字节进行反序列化——白名单永远不会检查这个内部对象图。

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.java | LogEventProxy.marshalledMessage 是 MarshalledObject<Message> |
log4j-core/impl/Log4jLogEvent.java | message() 调用 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链拼接进 MarshalledObject 的 objBytes,因此受害端无需任何攻击者自定义类即可触发RCE。
3.1 关键验证场景
| 场景 | 受害classpath | jdk.serialFilter | 结果 |
|---|---|---|---|
| 顶层发送被禁gadget | + gadget | 无 | 拒绝(FOIS白名单拦截) |
| gadget封装进LogEvent | + gadget | 无 | RCE(自动触发) |
| 顶层原始CC6 | log4j + cc-3.2.1 | 无 | 拒绝 |
| CC6拼接进MarshalledObject | log4j + cc-3.2.1 | 无 | RCE(无需攻击者类) |
| 上述载荷 | 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.sh或make 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自包含gadgetdocs/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序列化传输日志、且暴露在不可信网络的应用,都是潜在目标。
六、防御与缓解建议
由于官方补丁尚未发布,当前可采取的临时缓解措施如下:
- 结构级修复(首选):消除基于Java序列化的日志传输,改用JSON或RFC 5424格式,并通过认证的TLS通道传输。
- JVM过滤(有效但非透明):在接收端JVM设置
-Djdk.serialFilter='!java.rmi.MarshalledObject'。注意这会同时阻断合法的序列化LogEventProxy对象(它们也使用MarshalledObject)。 - 清理gadget依赖:移除或升级易受攻击的依赖库。例如
commons-collections3.2.1可被利用,而3.2.2已禁用不安全的functor反序列化。 - 暴露面收敛:不要在不可信网络上暴露基于FOIS的序列化日志接收端。
- 等待上游修复:官方建议的修复方案是——将
MarshalledObject从白名单中移除,并将封装的message迁移到Log4j过滤后的writeWrappedObject/readWrappedObject。
七、总结
Log4j2在Log4Shell余波五年之后,再次暴露出反序列化链路的深层隐患。本次漏洞的核心教训是:任何”白名单”过滤机制,只要允许了能在内部开启全新无过滤流的对象(如 MarshalledObject),就等于给攻击者留了一扇后门。
攻击者不需要完美的原生读写原语,不需要绕过复杂的沙箱——只需要一个”看起来无害”的对象,让框架自己把恶意载荷送进无过滤的反序列化流。这提醒所有安全人员:对序列化边界的信任,必须建立在”每一层都不信任”的原则之上。
在官方补丁发布前,建议所有使用Log4j 2.11.0至2.26.1、且存在日志序列化传输场景的企业,立即按上述缓解措施加固,并持续关注Apache官方仓库的修复进展。
参考资料:
- Apache Log4j2 Issue #4255:https://github.com/apache/logging-log4j2/issues/4255
- dinosn/log4j-4255 复现环境:https://github.com/dinosn/log4j-4255
- SecurityOnline 公开披露报告
- Apache Log4j CWE-502 FAQ:https://logging.apache.org/security/faq.html










暂无评论内容