转载:SpringBlade框架JWT认证缺陷漏洞CVE-2021-44910

转载自 奇安信攻防社区-SpringBlade框架JWT认证缺陷漏洞

文章中bladex的SIGN_KEY只在截图中体现,没有贴出来,这里补充下

bladexisapowerfulmicroservicearchitectureupgradedandoptimizedfromacommercialproject

---------------------------------------分割线--------------------------------------

1.前言

在某次代码审计项目中,发现项目代码是基于SpringBlade框架实现的,于是在审计的过程中,顺带着挖到了SpringBlade框架的一个0day漏洞。CVE编号:CVE-2021-44910

2.漏洞分析

SpringBlade前端通过webpack打包发布的,可以从其中找到app.js获取大量接口:


然后直接访问接口:api/blade-log/api/list


直接搜索“请求未授权”,定位到认证文件:springblade/gateway/filter/AuthFilter.java

2.1 错误的认证逻辑

我们看下代码逻辑:
(1)首先,从ServerWebExchange类中获取到uri,然后判断是否跳过:


跟进isSkip函数,如下:


判断路径是否在不需要认证的名单中,跟进getDefaultSkipUrl函数,看不需要认证的名单有哪些:


只要符合以上路径则不需要权限校验,否则都是需要权限校验的。而程序核心业务逻辑都是在/api/下的,显然需要授权。
(2)回到AuthFilter,接下来通过两种方式获取token,如果两者都为空时,则提示“缺失令牌,鉴权失败”。


我们跟进下AuthProvider.AUTH_KEY,看需要传入认证字符串的字段名称:



所以需要get或者在headers中有blade-auth,并从其中获取到鉴权字符串。
(3)解析token,判断token是否合法:


先看下getToken,实现如下:


这里解释下,为什么要从第七位取字符串,因为BEARER格式的认证串为:bearer[空格]认证字符。
接着看parseJWT方法的实现:


使用jwt密钥,对认证字符串进行解密,然后返回其内容,**如果解密结果不为空,则直接绕过认证。**那么继续往下,找JWT的解密过程及密钥:
看下JwtUtil.BASE64_SECURITY的值,如下:


是由TokenConstant.SIGN_KEY进行base64加密得来的。看一下TokenConstant.SIGN_KEY:


由此,我们可以伪造auth认证字符串了,测试:


带入接口测试:


成功伪造了任意用户进行登录。

[其他]
1、/api/blade-log/api/list接口中会泄漏账号密码,只要管理员登录过


2、部分情况下接口的前缀会被改,blade部分,可以从前端的app.js里面看得到完整接口。

2.2 权限提升

其实刚才伪造的用户只能算是普通用户,在测试时候,发现还有些接口用伪造的token访问不了


这个接口是查看系统用户的,结果没权限。找下其代码:


其中使用了PreAuth接口进行了鉴权,看下其鉴权方式:


调用了hasRole函数进行鉴权,找一下hasRole实现方式:(实现代码在:org/springblade/blade-core-secure/3.0.2/blade-core-secure-3.0.2.jar!/org/springblade/core/secure/auth/AuthFun.class)


跟进this.hasAnyRole方法:


跟进一下SecureUtil._getUser_方法,如下:


从web容器内部获取BLADE_USER的相关属性,如果没获取到的话,则会使用另外一个getUser方法,实现如下:


直接从请求头中获取blade-auth,然后进行jwt解密,将各个属性set给bladeUser类。
回到AuthFun.class,往下看:


其中r的来源是hasAnyRole被调用的时候传入的,我们看下传入的值:


所以,只需要我们在构造jwt的时候,加上role_name且其值为administrator,则可以实现权限提升。


试试token是否有效:


可见,权限进行了提升。
[注意]

1、/api/blade-user/user-list 接口会泄漏所有账号密码,不过需要administrator权限,不加role_name时,也可以,但无内容。


恰巧其登录时,直接用md5即可,所以,你懂的。
2、一般admin默认安装时,对应的id为:1123598811738675201,部分接口需要有对应的user_id,可以尝试。如:api/blade-user/info接口
3、jwt的密钥SIGN_KEY硬编码到jar里面了,而且不是写在配置文件里面,开发根本不会关注到这点,所以使用该框架的项目都受到影响。

3.修复方案

1、对于框架使用者而言,其实修改SIGN_KEY已经就让漏洞无法利用了
2、对于框架作者而言:
1)jwt的密钥,放在配置文件中,并提示用户修改。jar包里面硬编码改起来太麻烦
2)修改认证流程,本质还是认证流程出了问题。建议把用户账号、密码密文放到jwt里面,然后认证过程中,通过jwt里面的账号、密码进行鉴权。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Spring Security是Spring家族的一个安全管理框架,相比于另一个安全框架Shiro,它具有更丰富的功能。一般中大型项目都是使用Spring Security做安全框架,而Shiro上手比较简单。\[2\] JWT是一种用于身份验证和授权的开放标准,它定义了一种紧凑且自包含的方式来传输信息。JWT由三部分组成:头部、载荷和签名。头部包含了加密算法和类型信息,载荷包含了要传输的数据,签名用于验证数据的完整性和真实性。\[3\] 在Spring Security中集成JWT可以通过以下步骤实现: 1. 认证配置:配置Spring Security的认证流程,包括用户认证和生成JWT的逻辑。 2. 权限配置:配置Spring Security的权限控制,包括对不同角色和资源的访问控制。 通过以上配置,Spring Security可以使用JWT进行身份验证和授权,保护应用程序的安全性。 #### 引用[.reference_title] - *1* *2* [Spring Security+JWT简述](https://blog.csdn.net/jiangnb520/article/details/124921240)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring Security 之 JWT介绍](https://blog.csdn.net/weixin_40972073/article/details/126844751)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值