• 另类又不另类的shiro检测方式


    前言

    先随便唠叨几句,当碰到某个漏洞的时候,我们用工具直接去打,成功了就成功了,没成功我们也不知道为啥,即使是问出来为啥,可能不理解其中的含义也不知道说的啥。同事说我的文章都是别人写过的文章,然后截个图就完事了。我想说的是整个反序列化系列都是我跟随前人的步伐一步一步踏过来的,脚印很扎实。正所谓知其然不知其所以然,连探索精神都没有,我觉得那只能堕落,沉沦,灭亡。

    下面我们说文章。一般我们检测shiro的方法是用URLDNS链条或者cc链条去盲打,这篇文章来记录一下如何有效的检测shiro(检测是否为shiro,检测shiro的key)。

    密钥key不正确的时候

    当key错误的时候,我们知道 AbstractRememberMeManager#decrypt 是处理解密的过程。

    protected byte[] decrypt(byte[] encrypted) {
        byte[] serialized = encrypted;
        CipherService cipherService = this.getCipherService();
        if (cipherService != null) {
            ByteSource byteSource = cipherService.decrypt(encrypted, this.getDecryptionCipherKey());
            serialized = byteSource.getBytes();
        }
        return serialized;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    代码会走到cipherService.decrypt()这里,由于key是错误的,肯定解密不出来,下面来跟进一下代码。
    在这里插入图片描述
    解密错误会抛出异常,会进去最开始核心带代码AbstractRememberMeManager#getRememberedPrincipals(获取账号密码,当前用户)的catch逻辑。
    在这里插入图片描述
    跟进onRememberedPrincipalFailure方法
    在这里插入图片描述
    这个方法比较简单,debug会进入forgetIdentity方法。
    在这里插入图片描述
    forgetIdentity获取subjectContext对象中获取request, response,继续调用当前类的forgetIdentity方法。跟进removeFrom方法。
    在这里插入图片描述
    removeFrom方法调用this.addCookieHeader方法,添加了deleteMe字段。
    在这里插入图片描述

    gadget不正确,key正确时

    在这里插入图片描述

    第179行会先在执行deserialize方法去序列化我们的数据。
    在这里插入图片描述

    序列化完之后会强制转换成PrincipalCollection类型,由于我们的gadget数据没有继承或者不是PrincipalCollection类型的数据,所以会报错。
    在这里插入图片描述
    抛出了异常之后就会被 getRememberedPrincipals 的 catch 所捕获导致最终 header头中有 deleteMe
    在这里插入图片描述

    在这里插入图片描述

    解决

    那么怎么解决这个问题呢,需要我们的序列化数据继承PrincipalCollection类型即可,
    1.寻找一个继承 PrincipalCollection 的序列化对象。
    2.key正确情况下不返回 deleteMe ,key错误情况下返回 deleteMe 。
    基于着两个条件,找到SimplePrincipalCollection这个类,既继承了PrincipalCollection类,也可以被序列化,实现代码也简单

            SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection();
            ObjectOutputStream obj = new ObjectOutputStream(new FileOutputStream("result.ser"));
            obj.writeObject(simplePrincipalCollection);
            obj.close();
    
    • 1
    • 2
    • 3
    • 4

    key正确的时候:
    在这里插入图片描述
    key错误的时候:
    在这里插入图片描述

    参考:
    http://www.lmxspace.com/2020/08/24/%E4%B8%80%E7%A7%8D%E5%8F%A6%E7%B1%BB%E7%9A%84shiro%E6%A3%80%E6%B5%8B%E6%96%B9%E5%BC%8F/
    http://wjlshare.com/archives/1542
    https://blog.csdn.net/qq_41918771/article/details/121138580?spm=1001.2014.3001.5501
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    docker 配置mongoDB
    深入浅出Java线程池
    【Spring Boot】034-Spring Boot 整合 JUnit
    手把手教你搭建园林园艺小程序商城
    C++(11):to_string及stoi
    Kafka3.1简介及Kafka3.1部署、原理和API开发使用介绍
    C# WPF: Imag图片填充方式有哪些?
    Codeforces Round #821 (Div. 2)
    sql注入的其他注入
    Spring三级缓存解决循环依赖
  • 原文地址:https://blog.csdn.net/m0_67265464/article/details/126565342