游客发表

log4j1217漏洞

发帖时间:2026-10-17 04:59:16

2021年12月9日深夜,漏洞阿里云安全团队的漏洞钉钉群弹出一条告警:某个Java应用的日志里出现了从未见过的JNDI调用字符串。值班工程师起初以为是漏洞误报——log4j这个日志组件太老了,老到很多人觉得它不可能出问题。漏洞他把样本丢进沙箱跑了一遍,漏洞三分钟后,漏洞整个群安静了。漏洞

Log4j 2.x 的漏洞 lookup 功能允许在日志内容里嵌入类似 ${ jndi:ldap://...} 的表达式。设计初衷是漏洞方便运维动态读取环境变量,但没人想到,漏洞攻击者只要在任何一个会被记录的漏洞地方——用户名、User-Agent、漏洞聊天消息——填入这串字符,漏洞log4j 就会乖乖去连接远程服务器,漏洞加载并执行恶意代码。漏洞整个过程不需要用户点击,不需要额外权限,日志一写,代码就跑起来了。

这个漏洞后来被命名为 CVE-2021-44228,圈内人更习惯叫它“log4shell”。CVSS 评分满分10分。受影响范围覆盖了几乎所有用 Java 写的主流框架:Spring Boot、Struts、Kafka、Elasticsearch……有人统计过,Maven Central 上超过 8% 的包直接依赖 log4j-core。换句话说,互联网的半壁江山都在这个日志库的阴影下运行。

12月10日凌晨,GitHub 上开始出现零星的 PoC 仓库。到早上六点,Twitter 安全圈已经炸了。我印象很深的是一个叫 @_JohnHammond 的博主发的演示视频:他在自己的 Minecraft 服务器聊天框里输入了一串构造好的字符串,几秒后,服务器直接弹出了计算器。评论区有人说“这他妈是游戏啊”,有人说“我公司的内网Wiki也中招了”。

真正让事态失控的是攻击门槛。不需要逆向、不需要免杀、不需要0day储备。一个刚学会用 Burp Suite 的新手,复制粘贴一串 payload,就能拿下大量未修复的服务器。12月11日到14日那几天,全球蜜罐网络记录到的 JNDI 注入尝试从每小时几百次暴涨到每分钟上万次。攻击载荷从最初的反弹 shell 进化到挖矿、勒索、建立持久化后门,甚至有人把漏洞利用包装成“免费Log4j检测工具”在暗网兜售。

Apache 软件基金会的反应不算慢。12月10日发布了 2.15.0-rc1,但很快被发现绕过——攻击者可以用 ${ ${ lower:j}ndi:...} 这种嵌套写法绕过正则过滤。接着是 2.16.0,默认禁用了 JNDI。再后来是 2.17.0,又修了一个 DoS 问题。那两周里,运维和安全团队几乎没合过眼。我认识的一个银行安全负责人说,他们连夜扫描了三千多个应用实例,发现四百多个还在用 log4j 1.x——那个版本虽然不受这个漏洞影响,但早就不维护了,谁知道还藏着什么。

这件事暴露的不只是一个组件的缺陷。Log4j 的 lookup 功能存在了很多年,开源社区默认“日志内容不可信”这条边界被长期忽视。开发者习惯把用户输入直接丢进 logger.info(),没人觉得这有什么问题。直到有人证明,日志本身就可以是攻击载荷。

更麻烦的是修复。Java 生态的依赖树深得吓人,很多项目间接依赖 log4j,自己都不知道。有家公司排查了两周,最后在一个五年前写的内部工具里找到了漏洞入口——那个工具早就没人维护,但还在生产环境跑着。软件供应链的透明度问题被彻底摆上台面。SBOM(软件物料清单)从“建议”变成了“必须”。

2022年之后,log4j 的下载量不降反升。不是因为大家没升级,而是因为新项目还在用,旧项目改不动。很多团队的选择是加一层 WAF 规则,或者设置 log4j2.formatMsgNoLookups=true,先把洞堵上再说。彻底重构?排期排到了下个财年。

现在回头看,log4shell 没有“结束”的那一天。它变成了一个长期存在的背景噪音。每次有新的 JNDI 注入变种出现,安全圈都会条件反射地紧张一下。那个深夜的钉钉告警,改变了很多东西——比如我现在写 Java 代码,看到 logger.info(userInput) 会下意识地停顿两秒。

    热门排行

    友情链接