01.Shiro CBC 默认 KEY(<1.4.2)
shiro 是一个用于处理身份验证、授权、会话管理等安全功能的 Java 框架。在 Shiro 的配置中,有一个关键的密钥(Secret Key)用于加密和解密数据,通常称为"RememberMe Cookie Key"。该密钥用于保护 RememberMe 功能中的 Cookie 数据。
Shiro 默认配置中的这个密钥通常是硬编码的,这就导致了一个潜在的安全风险,即攻击者可以利用这个硬编码的密钥来伪造或解密 RememberMe Cookie,从而获得对应用程序的未经授权访问权限。这个问题被称为 Shiro 默认 key 漏洞。
在 Shiro 1.2.4 版本及之前的版本中,存在一个严重的漏洞,该漏洞允许攻击者通过伪造 Cookie 来绕过身份验证,进而访问应用程序中的受保护资源。 该漏洞涉及到 Shiro 在处理 RememberMe 功能时使用的默认密钥,它在特定情况下使用了一种不安全的加密模式(CBC 模式)。
#
示例代码:{ DefaultQuery: "", Path: "/shiro/cbc", Title: "Shiro CBC 默认KEY(<1.4.2)", Handler: func(writer http.ResponseWriter, request *http.Request) { failNow := func(writer http.ResponseWriter, request *http.Request, err error) { // 设置一个带有特殊值的cookie cookie := http.Cookie{ Name: "rememberMe", Value: "deleteMe", Expires: time.Now().Add(7 * 24 * time.Hour), HttpOnly: false, } http.SetCookie(writer, &cookie) writer.WriteHeader(200) if err != nil { writer.Write([]byte(err.Error())) } return } successNow := func(writer http.ResponseWriter, request *http.Request) { writer.WriteHeader(200) return } rememberMe, err := request.Cookie("rememberMe") if err != nil { // 如果请求中没有rememberMe Cookie,则设置一个特殊的Cookie failNow(writer, request, err) return } cookieVal, _ := codec.DecodeBase64(rememberMe.Value) var iv []byte if len(cookieVal) > len(randKey) { iv = cookieVal[:16] cookieVal = cookieVal[16:] } else { // 第一次请求探测 failNow(writer, request, err) return } payload, err := codec.AESCBCDecrypt(randKey, cookieVal, iv) if err != nil || payload == nil { // 如果解密失败,返回deleteMe failNow(writer, request, err) return } payload = codec.PKCS7UnPadding(payload)
checkGadget(payload, failNow, successNow, writer, request) return }, RiskDetected: true,}
#
攻击示例:攻击者可以模拟特定 Cookie,并将其发送到漏洞受影响的应用程序。通过在 Cookie 中伪造特殊的值,攻击者可以引发解密失败,绕过身份验证。
这里使用 Yakit 插件《Shiro 指纹识别 + 弱密码检测》
#
防御措施:- 更新 Shiro 版本: 更新至更高版本,以修复该漏洞。
- 自定义密钥: 不要使用默认密钥,自定义 RememberMe Cookie 密钥,并确保它是随机生成的,以增加攻击者猜测密钥的难度。
- 监控和日志记录: 实施监控和日志记录,以检测和响应异常活动,例如多次无效的 RememberMe Cookie 尝试。
- 限制 RememberMe 功能: 如果不是必需,可以考虑禁用 RememberMe 功能,以减少相关风险。