一、背景
2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。Apache Log4j2是一款优秀的Java日志框架。
Apache Log4j2.14.1之前版本中的配置、日志消息和参数中使用的 JNDI 功能不能防止攻击者控制的 LDAP 和其他 JNDI 相关端点。当启用消息查找替换时,可以控制日志消息或日志消息参数的攻击者可以执行从 LDAP 服务器加载的任意代码。从 log4j 2.15.0 开始,默认情况下已禁用此行为。由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。漏洞利用无需特殊配置,经阿里云安全团队验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。阿里云应急响应中心提醒 Apache Log4j2 用户尽快采取安全措施阻止漏洞攻击。
【漏洞评级】:严重
【漏洞编号】:CVE-2021-44228
【受影响的版本】:ApacheLog4j 2.x <= 2.14.1
更多详情参见:
https://issues.apache.org/jira/browse/LOG4J2-3201
https://issues.apache.org/jira/browse/LOG4J2-3198
https://logging.apache.org/
二、漏洞原理及复现
网络示例:比如log4j在以下项目中的调用:这里使用log4j2.12版本
配置文件如下所示:
测试程序如下:执行后打印用户名到日志
当修改程序变量,使打印到日志里的变量为:$参数,这种
如上所述,调用log4j打印参数时会执行:$后的参数,如上所述,代码执行后打印出了系统的信息到日志中了。
引入一个攻击类模拟注入:
类的内容:执行该类会打开notepad,即打开一个文本编辑器对话框
执行代码后,我们会发现上述代码被执行,预期弹出Notepad文本编辑器:
试想以下,如果时删除,或其他恶意破坏的代码回事什么后果;该漏洞就是利用可以执行JNDI协议方法调用,完成恶意注入。我们修改第一步的代码使用官方推荐的2.15版本:
再次执行代码:发现$参数不在被执行,而是以字符串的形式正常输出了
总结:上述整个案例过程如下:
原先漏洞,调用log4j时,就会找JNDI,执行引起的代码,执行完成传给浏览器用户侧。修复后,执行调用JNDI协议这种行为默认不再可用,从而避免相关注入执行。
三、处理
2.1、软件升级
强烈建议用户升级到log4j-2.15.0-rc2。
已发现官方修复代码,参考:
https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc1
软件下载:
wget -O https://www.apache.org/dyn/closer.lua/logging/log4j/2.15.0/apache-log4j-2.15.0-bin.tar.gz
2.2、临时方案
版本 >=2.10 缓解方案:
1.建议JDK使用6u211、7u201、8u191、11.0.1及以上的版本;
2.添加jvm启动参数:-Dlog4j2.formatMsgNoLookups=true;
3.添加log4j2.component.properties配置文件,增加如下内容为:log4j2.formatMsgNoLookups=true;
4.系统环境变量中将FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS设置为true;
5.禁止安装log4j的服务器访问外网,并在边界对dnslog相关域名访问进行检测。
2.0-beta9 到 2.10.0 的版本,缓解措施是:
从类路径中删除 JndiLookup 类: zip -q -d log4j-core-*.jar /org/apache/logging/log4j/core/lookup/JndiLookup.class
四、相关参考
Log4j入门使用教程 http://www.linuxidc.com/Linux/2013-06/85223.htm
Hibernate配置Log4j显示SQL参数 http://www.linuxidc.com/Linux/2013-03/81870.htm
Log4j学习笔记(1)_Log4j 基础&配置项解析 http://www.linuxidc.com/Linux/2013-03/80586.htm
Log4j学习笔记(2)_Log4j配置示例&Spring集成Log4j http://www.linuxidc.com/Linux/2013-03/80587.htm