fastjson漏洞利用

发布时间 2023-03-27 14:59:45作者: lisenMiller

基础预备

JNDI java name and directory invoke

JNDI是一组应用程序接口 提供了查找和访问命名和目录服务的通用,统一接口 java name and Directory interface

RMI

RMI 远程方法调用 依赖JRMP Java remote message protocol 再rmi中对象通过序列化的方式进行编码传输

远程对象

远程方法调用涉及参数传递和执行返回 任何被远程调用的方法的对象必须实现java.rmi.remote接口 远程对象实现类必须继承unicastRemoteObject类

进行通信时,RMI传递了一个远程对象的stub stub包含了远程对象的定位信息(socket端口,服务器主机地址 底层网络通信细节) 客户端和服务端主要是通过socket进行真实的调用

 

1.Server端监听一个端口,这个端口是JVM随机选择的;

2.Client端并不知道Server远程对象的通信地址和端口,但是Stub中包含了这些信息,并封装了底层网络操作;

3.Client端可以调用Stub上的方法;

4.Stub连接到Server端监听的通信端口并提交参数;

5.远程Server端上执行具体的方法,并返回结果给Stub;

6.Stub返回执行结果给Client端,从Client看来就好像是Stub在本地执行了这个方法一样;

RMI注册表

JDK提供了RMIregistry来实现获得远程对象的stub 

RMIRegistry 也是远程对象 默认监听在1099端口 

IHello rhello = newHelloImpl();
LocateRegistry.createRegistry(1099);
Naming.bind("rmi://0.0.0.0:1099/hello", rhello);

LocateRegistry.getRegistry()会使用给定的主机和端口等信息本地创建一个Stub对象作为Registry远程对象的代理,从而启动整个远程调用逻辑。服务端应用程序可以向RMI注册表中注册远程对象,然后客户端向RMI注册表查询某个远程对象名称,来获取该远程对象的Stub。

Registry registry = LocateRegistry.getRegistry("kingx_kali_host",1099);
IHello rhello = (IHello) registry.lookup("hello");
rhello.sayHello("test");

 

 从客户端角度看,服务端应用是有两个端口的,一个是RMI Registry端口(默认为1099),另一个是远程对象的通信端口(随机分配的)

动态加载类 

当jvm没有某个类的定义 可以从远程url下载这个类的calss 动态加载的calss文件可以使用web服务的方式进行托管

JNDI注入的利用方式借助了动态加载类的思路

JNDI注入

JNDI支持多种命名和目录提供程序 ,RMI注册表服务提供程序 (RMI Registry Service Provider) 允许通过JNDI应用接口对RMI中注册的远程对象进行访问操作 能够更加透明和统一

RMI客户端直接通过URL来定位一个远程对象,而且该RMI服务可以和包含人员,组织和网络资源等信息的企业目录链接在一起。

 

 JNDI接口在初始化时,可以将RMI URL作为参数传入,JNDI注入就出现在客户端的lookup()函数中,关键是参数能不呢个控制

Hashtable env = newHashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
//com.sun.jndi.rmi.registry.RegistryContextFactory 是RMI Registry Service Provider对应的Factory
env.put(Context.PROVIDER_URL, "rmi://kingx_kali:8080");
Context ctx = newInitialContext(env);
Object local_obj = ctx.lookup("rmi://kingx_kali:8080/test");

(11条消息) Fastjson系列漏洞实战和总结_jammny的博客-CSDN博客