我是靠谱客的博主 完美鸵鸟,最近开发中收集的这篇文章主要介绍Apache Log4j2漏洞序言日志框架SpringBoot集成日志框架CVE-2021-44228LDAPJNDI,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

序言

最近又爆出Apache Log4j2的大漏洞(CVE-2021-44228),很多使用了该框架的应用都受到了影响。影响范围极大,攻击者只需要向目标输入一段代码,不需要用户执行任何多余操作即可触发该漏洞,使攻击者可以远程控制受害者服务器。

由于Log4j 是目前全球使用最广泛的Java日志框架之一。该漏洞还影响着很多开源组件,如 Apache Struts2、Apache Solr、Apache Druid、Apache Flink 等。因为该漏洞利用方式简单,一旦有攻击者利用该漏洞,就可以在目标服务器上执行任意代码,给被攻击者造成极大危害。

解决方法即升级到高于解决CVE-2021-44228漏洞的版本(传送门:Log4j – Apache Log4j 2)。

日志框架

先来了解一下日志门面框架Slf4j以及实现框架log4j和logback等。

SLF4J(Simple logging Facade for Java)即Java简单日志门面(如果不了解门面模式的可以参看文末链接1),把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口。引用别人的下面那个图比较清楚,SLF4j是对外提供统一的API接口,下面绑定了具体的实现框架,如果你的pom文件中引用了多个,如logback和log4j都引用了会提示警告Class path contains multiple SLF4J bindings。 

SpringBoot集成日志框架

Springboot项目集成日志框架比较容易,直接在pom文件中添加依赖,在需要的地方调用日志框架API的LoggerFactory类中的getLogger静态方法,该方法再去调用日志工厂接口的getLogger实现方法(log4j或者logback的实现方法)。

            <!-- log -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

日志文件配置如下,

下面最后一行是使用logback的高级特性直接加在logback-spring-local.xml的配置文件,如果不区分本地环境、测试环境、生产环境配置则不需要指定,详细配置可参考链接4.

logging:
  # 日志输出格式
  pattern:
    # 文件日志输出格式:     时间格式       线程名称   日志级别  日志输出类  日志信息
    file: "%d{yyyy/MM/dd-HH:mm:ss} {%thread} %-5level %logger- %msg%n"
    console: "%d{yyyy/MM/dd-HH:mm:ss} {%thread} %-5level %logger- %msg%n"
  # 配置日志生成路径,下一日运行时会把前一日的日志文件打包成压缩包
  file:
    name: /Users/kaizhang/workspace/log/basic.log
  # 配置日志输出级别,error以上级别输出 ,默认输出日志级别:INFO(即包含INFO<WARING<ERROR)
  level:
    # 默认全局
    root: error
    # 在指定类下最低日志输出级别
    com.hust.zhang.web.controller.HomeController: debug
  # 加载指定目录下的日志输出配置文件
  # config: classpath:log/logback-spring-local.xml

CVE-2021-44228

官方解释:When the logging configuration uses a non-default Pattern Layout with a Context Lookup (for example, $${ctx:loginId}), attackers with control over Thread Context Map (MDC) input data can craft malicious input data using a JNDI Lookup pattern, resulting in an information leak and remote code execution in some environments and local code execution in all environments; remote code execution has been demonstrated on macOS but no other tested environments.

CVE(Common Vulnerabilities & Exposures)通用漏洞披露是一个字典表,记录着广泛认同的信息安全漏洞,上面相当于全球注册的唯一标识标记该漏洞。

LDAP

LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。

常见的应用场景是进行统一登录,参看:LDAP认证登录 - 应用身份服务 - 阿里云

JNDI

JNDI(Java Naming And Directory Interface,Java命名服务和目录接口)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI服务供应接口(SPI,Serial Peripheral Interface)的实现,由管理者将JNDI API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。

JDBC连接数据库的弊端:

  1. 参数变动引发URL修改
  2. 数据库产品切换,驱动包修改(eg:mysql —> oracle)
  3. 连接池参数的调整

由于JDBC连接数据库存在一些弊端,所以可以通过JNDI来实现命名服务和目录服务的交互。

命名服务

命名服务用于根据名字找到位置、服务、信息、资源、对象。

  1. 发布服务bind
  2. 查找服务lookup

比如使用JDNI方式去建立数据库连接,在application.yaml文件中配置spring.datasource.jndi-name属性

spring:
  application:
    name: hust-zhang
  profiles:
    active: local
  datasource:
    jndi-name: jdbc/exampleDB

配置中加载的命名服务是在context.xml里配置的资源

<Context>
    <!-- apache-tomcat/config/context.xml -->
    <Resource name="jdbc/exampleDB"
              auth="Container"
              type="javax.sql.DataSource"
              username="root"
              password="123456"
              driverNameClass="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/testdemo"
              maxTotal="8"
              maxIdle="4"/>
</Context>

JNDI提供的接口屏蔽了访问底层的一些细节,对于application.yaml文件来说配置始终不变,需要改的是目录服务中的context.xml配置。

JNDI动态协议转换

当我们调用lookup()方法时,如果lookup方法的参数像demo中那样是一个uri的地址,那么客户端就会去lookup()方法参数指定的uri中加载远程对象。

JNDI Naming Reference命名引用

当有客户端通过lookup("refObj")获取远程对象时,获取的是一个Reference存根(Stub),由于是Reference的存根,所以客户端会先在本地的classPath中去检查是否存在类refClassName,如果不存在则去指定的url动态加载。

 JNDI注入

JNDI注入流程如下图所示,调用JNDI接口时传入恶意参数,访问目录服务获取Reference存根。然后访问LDAP目录服务中不存在的refClassName。从指定地址动态加载Exploit对象,Exploit对象的静态代码块可以执行打开计算器操作。RMI(Remote Method Invocation,远程方法调用)也可以通过这种方式实现攻击。

public class Exploit {
    static {
        try {
            // 适用于windows系统命令行打开计算器
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

参考:

1、JAVA设计模式之门面模式(外观模式) | 菜鸟教程

2、logback:Logback Home

3、log4j:​​​​​​Log4j – Apache Log4j 2

4、【IT老齐084】Spring Boot Logback日志配置_哔哩哔哩

5、史上最详细Log4j高危漏洞解析_哔哩哔哩_bilibili

6、Apache Log4j代码执行漏洞(CVE-2021-44228)_ErYao7的博客-CSDN博客

最后

以上就是完美鸵鸟为你收集整理的Apache Log4j2漏洞序言日志框架SpringBoot集成日志框架CVE-2021-44228LDAPJNDI的全部内容,希望文章能够帮你解决Apache Log4j2漏洞序言日志框架SpringBoot集成日志框架CVE-2021-44228LDAPJNDI所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部