栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java代码审计——RMI基础

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java代码审计——RMI基础

0x00 前言

反序列化总纲

之前学过的RMI已经丢了,现在重新做笔记找回,如有不当之处,还请指明。

0x01 RPC

首先看一下最基础的解释,Java RMI是实现了RPC的Java API。那么看RMI之前,想先看看RPC

1.基础解释

RPC,Remote Procedure Call 远程过程调用。就是通过一种方式去远程的调用另外一个服务上的方法或者功能。

2.RPC需要解决的问题
  • 解决分布式系统中,服务之间的调用
  • 远程调用像本地调用一样方便
3.基本过程

1、A调用远程B
2、将调用的信息以序列化的方式进行发送
3、B接受信息,然后反序列化
4、将内容执行,然后以序列化的方式返回结果
5、A反序列化拿到结果

0x02 RMI

RMI就是Java中对RPC的一种实现,对其进行了封装

在RMI中使用的是jrmp协议:JRMP是的Java技术协议的具体对象为希望和远程引用。JRMP只能是一个Java特有的,基于流的协议。相对于的RMI - IIOP的 ,该协议JRMP只能是一个对象的Java到Java的远程调用,这使得它依赖语言,意思是客户端和服务器必须使用Java。

1.Demo

首先创建一个远程调用目标的接口:

package server;

import java.io.IOException;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface HelloRegistryFacade extends Remote {

    String helloWorld(String name) throws IOException;

}

实现这个接口:

package server;

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

public class HelloRegistryFacadeImpl extends UnicastRemoteObject implements HelloRegistryFacade{

    public HelloRegistryFacadeImpl() throws RemoteException {
        super();
    }

    @Override
    public String helloWorld(String name) throws IOException {
        Runtime.getRuntime().exec("calc");
        return name;
    }

}

客户端:

package server;

import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RegistryClient {
    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.getRegistry(1099);
            HelloRegistryFacade hello = (HelloRegistryFacade) registry.lookup("HelloRegistry");
            String response = hello.helloWorld("zhangsan");
            System.out.println("=======> " + response + " <=======");
        } catch (NotBoundException | RemoteException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端:

package server;

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

public class RegistryService {
    public static void main(String[] args) {
        try {
            // 本地主机上的远程对象注册表Registry的实例,默认端口1099
            Registry registry = LocateRegistry.createRegistry(1099);
            // 创建一个远程对象
            HelloRegistryFacade hello = new HelloRegistryFacadeImpl();
            // 把远程对象注册到RMI注册服务器上,并命名为HelloRegistry
            registry.rebind("HelloRegistry", hello);
            System.out.println("======= 启动RMI服务成功! =======");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

先运行客户端,然后再运行服务端:

2.利用限制
  • Java SecurityManager的限制,默认是不允许远程加载的
  • 属性 java.rmi.server.useCodebaseonly 的值必需为false。但是从JDK 6u45、7u21开始,java.rmi.server.useCodebaseonly 的默认值就是true
3.限制下利用

在限制下的时候,需要开启配置:demo如下

package server1;

import javax.naming.InitialContext;

public class RMIClient1 {
    public static void main(String[] args) throws Exception {
        System.setProperty("java.rmi.server.useCodebaseOnly", "false");
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
        String url = "rmi://127.0.0.1:666/Exploit";
        InitialContext initialContext = new InitialContext();
        initialContext.lookup(url);
    }
}

测试结果:

参考文章
  • https://paper.seebug.org/1091/#rmi
  • https://baike.baidu.com/item/jrmp/6099442?fr=aladdin
  • https://www.jianshu.com/p/de85fad05dcb
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678397.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号