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

题目附件👉下载

好像是当时场上攻击0解题,但挺多人得到了防御分

这两天又做了一遍,发现这题考察的知识点还挺多的

(第一次参加线下赛没能上网真的难绷😭,被队里另一个web✌和pwn✌带飞了)

前置知识(题目就给了这两个提示):

Analysis

只有一个控制器MessageController,对传入的message进行base64解码

image-20230622132240291

这个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.

大概就是跟序列化和反序列化有关的,而且这个又是kryo包下,题目也提示了Kryo反序列化

跟进CodecMessageConverter#toMessage

image-20230622150130904

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

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

回到toMessage,继续跟进decode

image-20230622151117090

将字节数组封装到Kryo自定义的输入流com.esotericsoftware.kryo.io.Input

一路跟进就到了熟悉的Kryo#readObject

调用栈👇

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

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

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

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

缝一下就能打了

Patch and POC

如何修复呢?

最粗暴的方式就是把几个关键类禁了,但由于这里是byte数组转字符串,可能存在一些类名卡一半

image-20230622155158515

这个方法是比赛的时候想到的,但我不会用Maven指定本地jar包位置。。。打包不了patch

要能上网一下子的事情🤬🤮,下次比赛记得弄个本地Maven镜像

也可以上RASP通防,不过我太菜了不会用🤧

完整POC:

Last updated

Was this helpful?