fastjson 1.22-1.24 漏洞复现与分析
前言
QAQ,感觉自己啥也不会,要好好努力学习了。但是由于本人遗忘度很大,因此要记下来学习QAQ。
概念
RMI(Remote Method Invocation)
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。
Java RMI极大地依赖于接口。在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。
乱七八糟的一大串,简单来说,RMI就是一个只java远程调用方法的行为。
JRMP(Java Remote Method Protocol)
Java远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的、用于查找和引用远程对象的协议。这是运行在Java远程方法调用(RMI)之下、TCP/IP之上的线路层协议(英语:Wire protocol)。
JNDI(Java Naming and Directory Interface)
Java命名和目录接口(Java Naming and Directory Interface,缩写JNDI),是Java的一个目录服务应用程序接口(API),它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。
就是一个接口,可以通过lookup方法访问其所绑定的对象。
示例代码
程序A
继承Remote的HelloService接口:
public interface HelloService extends Remote {
String sayHello() throws RemoteException;
}
HelloService的实现
public class HelloServiceImpl extends UnicastRemoteObject implements HelloService {
public HelloServiceImpl() throws RemoteException {
}
@Override
public String sayHello() throws RemoteException {
System.out.println("hello!");
return "hello!";
}
}
RMI服务端
public class RMIServer {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.createRegistry(1099);
registry.bind("hello", new HelloServiceImpl());
} catch (RemoteException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
}
程序B
public class RMIClient {
public static void main(String[] args) {
try {
HelloService helloService = (HelloService)LocateRegistry.getRegistry("127.0.0.1", 1099).lookup("hello");
System.out.println(helloService.sayHello());
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
先执行程序A再执行程序B就会打印hello。
程序A启动了一个RMI的注册中心,并把HelloServiceImpl暴露在注册中心中。程序B启动之后通过命名寻找方法,最后通过JRMP协议发起RMI请求,程序A输出hello后将信息序列化发送给程序B,最后程序B反序列化输出。
反序列化
反序列化有三个函数:
parse (String text)
parseObject(String text)
parseObject(String text, Class clazz)
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.Properties;
public class fastjsonTest {
public String t1;
private int t2;
private Boolean t3;
private Properties t4;
private Properties t5;
public String getT1() {
System.out.println("getT1()");
return t1;
}
public void setT1(String t1) {
this.t1 = t1;
System.out.println("setT1()");
}
public int getT2() {
System.out.println("getT2");
return t2;
}
public void setT2(int t2) {
System.out.println("setT2");
this.t2 = t2;
}
public Boolean getT3() {
System.out.println("getT3");
return t3;
}
public Properties getT4() {
System.out.println("getT4");
return t4;
}
public Properties getT5() {
System.out.println("getT5");
return t5;
}
public void setT5(Properties t5) {
System.out.println("setT5");
this.t5 = t5;