Poketto

一行日志就能让服务器执行攻击者的代码:Log4Shell 如何把十年老组件变成全球火警

目录

文章主题概念插画

配图:AI 生成的概念示意图,非论文原图、真实现场或实验数据。

TL;DR:2021 年 12 月,Java 日志库 Apache Log4j 2 被披露存在编号 CVE-2021-44228 的漏洞(俗称 Log4Shell),攻击者只要能让程序把一段特制字符串写进日志,就可能让服务器加载并执行远程代码。它的严重程度评分为满分 10.0,已确认被大规模利用。本文只讲这个漏洞本身,不涉及具体某家公司的损失数字,那些我没有核实。

这是 2021 年底的旧事,不是今天的新闻。2021 年 12 月上旬漏洞公开后,美国 CISA 在 12 月 17 日发布了针对联邦机构的紧急指令 22-02。

一行日志是怎么变成后门的

Log4j 是 Java 世界里极其常见的日志组件,作用只是“把程序想记的话写下来”。问题出在它的一个功能:日志内容里如果出现形如 ${jndi:ldap://...} 的片段,Log4j 会把它当成查询指令去解析,通过 JNDI 去联系指定的 LDAP 服务器,并加载对方返回的内容。

于是攻击链简单得吓人:攻击者把这串字符放进任何会被记录的地方,比如网站的 User-Agent、用户名、聊天消息,服务器一写日志,就会去连攻击者控制的服务器,并执行其下发的代码。无需登录,也无需用户点击。

为什么是“全球火警”

按 Apache 官方安全页面,受影响的是 log4j-core 的 2.0-beta9 到 2.14.1 等版本,只用 log4j-api 的不受影响;漏洞由阿里云安全团队的陈兆军报告。CVSS 3.1 评分 10.0,攻击途径为网络、复杂度低、无需权限、无需交互。

更麻烦的是它藏得深。CISA 指出,Log4j 广泛存在于消费级和企业服务、网站、应用以及工控类产品中,自研软件、不直接对外的系统和第三方 SaaS 也可能中招。很多团队连“我们到底用没用 Log4j”都答不上来,因为它往往是依赖的依赖。CISA 随后把该漏洞列入已知被利用漏洞目录,并明确提到存在活跃、大范围的利用。

补丁也不是一次到位

最初的修复是 2.15.0(Java 8 及以上),同时提供 Java 6 的 2.3.1 和 Java 7 的 2.12.2。但随后又出现了 CVE-2021-45046(2.16.0 修复,并默认禁用 JNDI)和 CVE-2021-45105(2.17.0 修复)等后续问题,CISA 后来的建议版本是 2.17.1(Java 8)、2.12.4(Java 7)、2.3.2(Java 6)。无法升级时,只能按 CISA 的临时缓解措施处理,实在不行就把资产断网。

教训

Log4Shell 的根源不是某个高深的攻击技巧,而是一个“好心”的功能:让日志库顺手帮你解析并联网查询字符串。它提醒大家,来自用户的任何输入都不可信,哪怕只是要被写进日志;也提醒大家,软件物料清单(知道自己依赖了什么)才是应急时跑得最快的基础设施。

来源:

关注这个空间,它的新文章会出现在你的关注动态里。