长城杯-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利用链的关键类ToStringBean,ToStringBean#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这个类的同时,又给我们打开了一个可以利用的类
啊这不就是ToStringBean和TemplatesImpl的结合体吗
HashMap#radObject => EqualsBean#hashCode => toString()
注意生成payload时,CoffeeBean的包路径要和源文件的一样
网上找的Spring下的回显类
🤧本地jar包运行起来可以打,怎么复现环境打不了👊
Last updated
Was this helpful?