Web渗透:Shiro550漏洞(CVE-2016-4437)

news2024/9/24 1:17:15

Apache Shiro 是一个强大且易于使用的Java安全框架,提供了身份验证(Authentication)、授权(Authorization)、会话管理(Session Management)和密码学支持等功能。Apache Shiro 550反序列化漏洞(CVE-2016-4437)是一个严重的Java反序列化漏洞,它允许攻击者通过特制的Java序列化对象在目标系统上执行任意代码。该漏洞影响了使用默认“rememberMe”功能的Apache Shiro。

shiro550(1.2.4版本)反序列化漏洞原理

Apache Shiro 提供了一种“rememberMe”功能,用于在用户关闭浏览器后仍然保持会话,当启用该功能时,Shiro 会将用户的会话信息序列化并存储在一个 cookie 中,以便在用户重新访问时反序列化并恢复会话;在这边攻击者可以通过修改“rememberMe” cookie,注入特制的恶意 Java 序列化对象;当 Shiro 反序列化这个恶意对象时,攻击者可以在目标系统上执行任意代码。

漏洞相关源代码片段

漏洞出现在 Shiro 的 RememberMeManager 组件中,特别是处理“rememberMe”cookie 的代码部分,以下是与漏洞相关的关键代码片段的简化示例,帮助我们理解漏洞的原理。

    public void onSuccessfulLogin(Subject subject, AuthenticationToken token, AuthenticationInfo info) {
        //清理旧的身份验证信息c
        forgetIdentity(subject);
​
        //生成新的身份验证信息
        if (isRememberMe(token)) {  //如果有勾选remember me
            rememberIdentity(subject, token, info);//生成新的cookie中的RememberMe字段

在Shiro中,当用户成功登录时,可以通过onSuccessfulLogin方法来处理“记住我”功能的逻辑。这个方法会清理旧的身份验证信息,并根据需要生成新的身份验证信息。

forgetIdentity方法会删除存储在Cookie中的身份信息,以确保旧的身份信息不会被重新使用。isRememberMe(token):检查登录请求中是否包含“记住我”选项。如果用户在登录时选择了“记住我”,这个方法会返回truerememberIdentity(subject, token, info):如果用户选择了“记住我”,这个方法会生成并存储新的身份验证信息;接着我们再继续追踪rememberIdentity

   public void rememberIdentity(Subject subject, AuthenticationToken token, AuthenticationInfo authcInfo) {
        PrincipalCollection principals = getIdentityToRemember(subject, authcInfo);
        rememberIdentity(subject, principals);
    }

getIdentityToRemember(subject, authcInfo)方法用于从authcInfo(身份验证信息)中提取用户的身份信息。接着调用rememberIdentity(subject, principals)方法,使用提取到的身份信息来设置“记住我”功能,这边继续跟进rememberIdentity:

    protected void rememberIdentity(Subject subject, PrincipalCollection accountPrincipals) {
        byte[] bytes = convertPrincipalsToBytes(accountPrincipals);
        rememberSerializedIdentity(subject, bytes);
    }
1.convertPrincipalsToBytes

这个函数中使用了convertPrincipalsToBytes(accountPrincipals)方法用于将PrincipalCollection(包含用户身份信息的对象)转换为字节数组;此时我们进入convertPrincipalsToBytes函数查看具体针对信息数据的操作是什么样的:

     protected byte[] convertPrincipalsToBytes(PrincipalCollection principals) {
        byte[] bytes = serialize(principals);
        if (getCipherService() != null) {
            bytes = encrypt(bytes);
        }
        return bytes;
    }

可以看到再这个函数中首先使用了serialize(principals)方法将PrincipalCollection对象序列化为字节数组。接着进行一个获取密钥服务的操作,当CipherService不为空,则对序列化后的字节数组进行加密;接着我们进入encryp函数中查看具体的加密操作是如何进行的:

    protected byte[] encrypt(byte[] serialized) {
        byte[] value = serialized;
        CipherService cipherService = getCipherService();  
        if (cipherService != null) {    //如果cipherService不为空
            ByteSource byteSource = cipherService.encrypt(serialized, getEncryptionCipherKey());   
            value = byteSource.getBytes();
        }
        return value;
    }

这里调用了getCipherService()方法获取配置的加密服务,并赋值给变量cipherService;进入getCipherService()方法后可以发现此处的加密为AES加密(除了指定加密的方式之外还指定了其他的一些加密细节)

获取到加密的信息后就是对序列化的数据进行加密了,在加密时,程序中使用了getEncryptionCipherKey()方法进行密钥获取:

此时可以看到默认的加密密钥实际上在shiro中是一串固定的base64解码后的字符串;其base64编码的值是“kPH+bIxk5D2deZiIxcaaaA==”

2.rememberSerializedIdentity

在清楚如何针对信息数据转化为字节数组后,接着再看一下rememberSerializedIdentity方法中具体做了哪些操作:

   protected void rememberSerializedIdentity(Subject subject, byte[] serialized) {
​
        if (!WebUtils.isHttp(subject)) {
            if (log.isDebugEnabled()) {
                String msg = "Subject argument is not an HTTP-aware instance.  This is required to obtain a servlet " +
                        "request and response in order to set the rememberMe cookie. Returning immediately and " +
                        "ignoring rememberMe operation.";
                log.debug(msg);
            }
            return;
        }
​
​
        HttpServletRequest request = WebUtils.getHttpRequest(subject);
        HttpServletResponse response = WebUtils.getHttpResponse(subject);
​
        //base 64 encode it and store as a cookie:
        String base64 = Base64.encodeToString(serialized);  //进行base64编码
​
        Cookie template = getCookie(); //the class attribute is really a template for the outgoing cookies
        Cookie cookie = new SimpleCookie(template);
        cookie.setValue(base64);    //将base64编码的信息整合到cookie当中
        cookie.saveTo(request, response);
    }

在该方法中使用了Base64.encodeToString(serialized);对序列化数据进行Base64编码;并将Base64编码后的数据整合到Cookie中;至此我们就可以知道RememberMe的具体生成步骤:

用户信息-->序列化-->AES加密-->Base64编码-->Cookie信息

那么对应的解密过程就是:

Cookie信息-->Base64解码-->AES解密-->反序列化-->用户信息

漏洞利用

靶场则是使用vulhub进行搭建,进入对应的目录.../vulhub/shiro/CVE-2016-4437;使用docker命令进行启动

docker-compose up -d

查看具体的端口映射

docker ps -a

这个时候直接访问环境所在靶机IP地址的8080端口:

默认的账号密码为admin:vulhub;这个时候我们可以先输入任意Username和passwrod进行登录并抓包(Remember me选项必须勾选);抓到数据包后将数据包发送至BP的重放模块Repeater,进行发包,查看相应包内容:

发现相应包中包含有Set-Cookie: rememberMe=deleteMe字段就基本上可以断定这边使用了shiro框架;既然是shiro框架,我们就可以尝试进行安全测试:

安全工具(文章末尾附下载地址)

①Burpsuite ShiroPassiveScan插件扫描

这是一款基于BurpSuite的被动式shiro检测插件;该插件会对BurpSuite传进来的每个不同的域名+端口的流量进行一次shiro检测且key可在config.yml自定义,解决有些用户觉得key太少的问题。

安装方法:

添加进入插件即可;

这当我们正常去访问网站, 如果站点的某个请求出现了,那么该插件就会去尝试检测(需要挂BP);当检测到漏洞后则会在BP中进行显示:

这款插件也允许我们自行添加Key:打开./BurpShiroPassiveScan/resources/config.yml并找到application.shiroCipherKeyExtension.config.payloads,在后面添加新的Key即可。

②shiro_attack

使用此工具需要事先准备java环境,java10以上版本缺少javafx-sdk-18.0.2泛型,需要自己手动安装,最好使用jdk1.8版本(环境变量的设置这边就不说了),环境准备好后直接在工具目录打开cmd命令行,运行如下命令:

java -jar shiro_attack-4.7.0-SNAPSHOT-all.jar

能够爆破出Key则表示Shiro框架存在反序列化漏洞,在爆破出Key后可以直接选择检测当前利用链条,若利用链不能够利用则可以进行利用链爆破;

发现利用链可以使用后则尝试进行命令执行、内存马操作,成功GetShell。

【注意】若懒得去找jdk1.8以及这两个工具,关注风铃Sec回复[Shiro550]进行领取即可(文章底下有二维码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1932309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

set类和map类介绍和简单使用

目录 set类介绍与简单使用 set类 multiset类 map类介绍与简单使用 map类 multimap类 set类介绍与简单使用 set类是一种关联式容器,在数据检索时比序列式容器效率更高。本质是一个常规的二叉搜索树,但是为了防止出现单支树导致效率下降进行了相关优…

188数码管轮询扫描

前言 最近用到了188数码管,总结一下。 188数码管,用5个IO,在不借助外部驱动芯片的情况下,可以点亮20个灯。188数码管广泛应用于电子烟、充电器、充电宝、DVD、高级音响、工业设备控制面板、医疗器械等多个领域,满足不…

FPGA FIR fdatool filter designer MATLAB

位数问题 fdatool 先确定输入信号的位宽,比如17位在fdatool中,选set quantization parameters 选input/output 设置input word length 为17bit(not confirmed) fir compiler implementation 注意: 当设置输入位宽为16位时,ip核…

Java 快速入门学习 -- Day 2

Java 快速入门 Ⅱ maven(图书管理员)IDEA使用 maven框架 maven(图书管理员) maven 仓库,图书馆。要看书的化先从家里找(本地仓库),本地找不到就去中央仓库或者镜像仓库找&#xff0c…

CSA笔记3-文件管理命令(补充)+vim+打包解包压缩解压缩命令

grep(-i -n -v -w) [rootxxx ~]# grep root anaconda-ks.cfg #匹配关键字所在的行 [rootxxx ~]# grep -i root anaconda-ks.cfg #-i 忽略大小写 [rootxxx ~]# grep -n root anaconda-ks.cfg #显示匹配到的行号 [rootxxx ~]# grep -v root anaconda-ks.cfg #-v 不匹配有…

记录些MySQL题集(8)

ACID原则、事务隔离级别及事务机制原理 一、事务的ACID原则 什么是事务呢?事务通常是由一个或一组SQL组成的,组成一个事务的SQL一般都是一个业务操作,例如聊到的下单:「扣库存数量、增加订单详情记录、插入物流信息」&#xff0…

AQS详解

文章目录 AQS 是什么?AQS 的原理是什么?AQS 资源共享方式总结 AQS 是什么? AQS 的全称为 AbstractQueuedSynchronizer ,翻译过来的意思就是抽象队列同步器。这个类在 java.util.concurrent.locks 包下面。 AQS是一个用来构建锁和…

【操作系统】定时器(Timer)的实现

这里写目录标题 定时器一、定时器是什么二、标准库中的定时器三、实现定时器 定时器 一、定时器是什么 定时器也是软件开发中的⼀个重要组件.类似于⼀个"闹钟".达到⼀个设定的时间之后,就执行某个指定 好的代码. 定时器是⼀种实际开发中⾮常常用的组件. ⽐如⽹络通…

base SAS programming学习笔记13(Array)

1.Array array-name{dimension} <elements> array-name&#xff1a;向量名称 dimension&#xff1a;向量长度&#xff0c;默认为1&#xff1b; elements:列出变量名&#xff0c;变量名要么全是数值变量或者全是字符变量 array-name和variable不能相同&#xff1b;也不能和…

【BUG】已解决:java.lang.IllegalStateException: Duplicate key

已解决&#xff1a;java.lang.IllegalStateException: Duplicate key 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市…

Java红娘婚恋相亲交友系统小程序源码

红娘婚恋相亲交友小程序&#xff1a;遇见爱情&#xff0c;从指尖开始&#x1f496; &#x1f4f1; 掌中红娘&#xff0c;随时待命 &#x1f48c; 在这个数字化时代&#xff0c;爱情也迎来了它的新舞台——“红娘婚恋相亲交友小程序”。只需轻轻一点&#xff0c;你的专属红娘就…

记录些MySQL题集(6)

MySQL 单表为什么不要超过 2000W 行&#xff1f; 数据持久化在磁盘中&#xff0c;磁盘的最小单元是扇区&#xff0c;一个扇区 0.5 KB&#xff0c;而由 8 个扇区可以构成一个文件系统块&#xff08;4K&#xff09;&#xff0c;以 InnoDB 存储引擎为例&#xff0c;一个数据页的大…

浅谈C嘎嘎类与对象

本篇文章与大家浅谈一下C嘎嘎的类与对象知识点 类的定义 关键字&#xff1a;class 语法格式&#xff1a; class 类名 { }&#xff1b;//这里的分号不能少 此外&#xff0c;class有三个属性分别是private、public、protected&#xff0c;这三个属性是干啥的&#xff0c;相…

昇思25天学习打卡营第13天|CycleGAN 图像风格迁移互换全流程解析

目录 数据集下载和加载 可视化 构建生成器 构建判别器 优化器和损失函数 前向计算 计算梯度和反向传播 模型训练 模型推理 数据集下载和加载 使用 download 接口下载数据集&#xff0c;并将下载后的数据集自动解压到当前目录下。数据下载之前需要使用 pip install dow…

如何PR到别人仓库(指定分支,无废话)

如何PR到别人仓库&#xff08;指定分支&#xff09; 记录一下&#xff0c;之前都是直接master分支&#xff0c;现在记录如何pr到别人仓库的其他分支 首先进入别人仓库然后点击fork到自己仓库 步骤&#xff08;以博主自己一个例子为例&#xff09; &#xff08;1&#xff09;…

配置和保护SSH

使用SSH访问远程命令行 描述Secure Shell SSH&#xff08;Secure Shell&#xff09; 是一种网络协议&#xff0c;用于在不安全的网络上安全地进行系统管理和数据传输。它最初由 Tatu Ylnen 于1995年设计&#xff0c;并成为保护网络服务免受攻击的标准。SSH提供了多种功能&…

prometheus+grafana应用监控配置

配置Prometheus 官方地址&#xff1a;Download | Prometheus &#xff08;wegt下载压缩包&#xff0c;解压并重命名prometheus&#xff0c;文件放于/data/prometheus即可&#xff09; 配置 service方法(文件放于 /etc/systemd/system/prometheus.service)&#xff1a; [Unit…

Windows与Ubuntu安装ffmpeg

文章目录 前言ffmpeg的简介安装ffmpegWindows下载设置环境变量 Ubuntu 总结 前言 FFmpeg是一款非常强大的开源音视频处理工具&#xff0c;它包含了众多的音视频编解码库&#xff0c;可以用于音视频的采集、编解码、转码、流化、过滤和播放等复杂的处理。在Windows系统上安装FF…

Talk|清华大学袁天远:PreSight - 利用NeRF先验帮助自动驾驶场景在线感知

本期为TechBeat人工智能社区第605期线上Talk。 北京时间7月3日(周三)20:00&#xff0c;清华大学博士生—袁天远的Talk已经准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “PreSight - 利用NeRF先验帮助自动驾驶场景在线感知”&#xff0c;他向大家介绍了新…

OBD诊断(ISO15031) 08服务

文章目录 功能简介ISO 9141-2、ISO 14230-4和SAE J1850的诊断服务定义1、请求控制车载设备请求消息&#xff08;读取支持的TID&#xff09;2、请求控制车载设备响应消息&#xff08;报告支持的TID&#xff09;3、请求控制车载设备请求消息&#xff08;读取TID值&#xff09;4、…