长城杯-b4bycoffee (ROME反序列化)

复现地址👉[NSSCTF - 长城杯 2022 高校组]b4bycoffee (ctfer.vip)

查看POM文件,存在ROME依赖

<dependency>
    <groupId>com.rometools</groupId>
    <artifactId>rome</artifactId>
    <version>1.7.0</version>
</dependency>
@RequestMapping({"/b4by/coffee"})
    public Message order(@RequestBody CoffeeRequest coffee){
        if (coffee.Venti != null) {
            InputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(coffee.Venti));
            AntObjectInputStream antInputStream = new AntObjectInputStream(inputStream);
            Venti venti = (Venti)antInputStream.readObject();
            return new Message(200, venti.getcoffeeName());
        } // ...
    }

AntObjectInputStream是自定义的对象输入流类,维护了一个黑名单

我们知道ObjectInputStream#resolveClass用于加载类,其默认实现实际就是调用了Class.forName(name, false,loader)readObject需要经过resolveClass

AntObjectInputStream禁用了ROME利用链的关键类ToStringBeanToStringBean#toString能够调用类的getter方法。

public class AntObjectInputStream extends ObjectInputStream {
    private List<String> list = new ArrayList();

    public AntObjectInputStream(InputStream inputStream) throws IOException {
        super(inputStream);
        this.list.add(BadAttributeValueExpException.class.getName());
        this.list.add(ObjectBean.class.getName());
        this.list.add(ToStringBean.class.getName());
        this.list.add(TemplatesImpl.class.getName());
        this.list.add(Runtime.class.getName());
    }

    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (this.list.contains(desc.getName())) {
            throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
        } else {
            return super.resolveClass(desc);
        }
    }
}

题目断掉ToStringBean这个类的同时,又给我们打开了一个可以利用的类

啊这不就是ToStringBeanTemplatesImpl的结合体吗

HashMap#radObject => EqualsBean#hashCode => toString()

注意生成payload时,CoffeeBean的包路径要和源文件的一样

网上找的Spring下的回显类

🤧本地jar包运行起来可以打,怎么复现环境打不了👊

Last updated

Was this helpful?