某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

  • 客户端主题(翻译)

  • 高级主题(翻译)

    • 高级主题
    • 不安全的反序列化

    • Web LLM攻击

    • GraphQL API漏洞

    • 服务端模板注入

    • Web缓存投毒

    • HTTP主机头攻击

    • HTTP请求走私

    • OAuth身份验证漏洞

    • JWT攻击

      • JWT攻击
      • 算法混淆攻击
        • 算法混淆攻击
        • 对称与非对称算法
        • 算法混淆漏洞是如何产生的?
        • 实现算法混淆攻击
          • 步骤1-获取服务器的公钥
          • 步骤2-将公钥转换为合适的格式
          • 步骤3-修改你的JWT
          • 步骤4-使用公钥对JWT进行签名
        • 从现有令牌中导出公钥
    • 原型链污染

    • 基本技能

  • 扩展阅读(翻译)

  • 个人学习笔记

  • 实验室做题记录

  • BurpSuite及官方实验室
  • 高级主题(翻译)
  • JWT攻击
carsaid
2024-02-13
目录

算法混淆攻击

翻译

原文:https://portswigger.net/web-security/jwt/algorithm-confusion

- name: 翻译
  desc: 原文:https://portswigger.net/web-security/jwt/algorithm-confusion
  bgColor: '#F0DFB1'
  textColor: 'green'
1
2
3
4

# 1算法混淆攻击

算法混淆攻击(也称为密钥混淆攻击)发生时,攻击者可以强制服务器使用不符合预期的算法来验证 JSON Web Token(JWT (opens new window))签名。如果处理不当,攻击者就可以伪造包含任意值的有效 JWT,而无需知道服务器的私有签名密钥。

# 2对称与非对称算法

对 JWTs 进行签名时,可以使用一系列不同的算法。其中某些算法使用 “对称” 密钥,例如 HS256(HMAC + SHA-256),这意味着服务器将会使用 单个密钥 来对令牌进行签名和验证。显然,这个密钥的机密性需要得到保证,就像密码一样。

Not Found Image

另一些算法使用 “非对称” 的密钥对,例如 RS256(RSA + SHA-256)。这对密钥是由一个私钥 和 一个与数学相关的公钥组成的,服务器使用私钥对令牌进行签名,而公钥可用于验证签名。

Not Found Image

顾名思义,私钥必须保密;公钥通常是共享的,以便任何人都可以对 服务器颁发的令牌签名 进行验证。

# 3算法混淆漏洞是如何产生的?

算法混淆漏洞通常是由于 JWT 库的实现有缺陷而产生的。尽管实际的验证过程因所使用的算法而异,但许多库都提供了一种与算法无关的单一方法来验证签名。这些方法依赖于令牌标头中的alg参数,根据参数值来确定应执行哪种类型的验证。

下面的伪代码展示了一个简化版的示例,说明了这个通用方法verify()在 JWT 库中的大致写法:

function verify(token, secretOrPublicKey){
    algorithm = token.getAlgHeader();
    if(algorithm == "RS256"){
        // Use the provided key as an RSA public key
    } else if (algorithm == "HS256"){
        // Use the provided key as an HMAC secret key
    }
}
1
2
3
4
5
6
7
8

随后,假设网站开发人员使用此方法,用来处理非对称算法(如 RS256)所签名的 JWTs,就会出现问题。由于使用了非对称算法,他们可能总是会将一个 固定的公钥 传递给该方法,如下所示:

publicKey = <服务器公钥>;
token = request.getCookie("session");
verify(token, publicKey);
1
2
3

此时,如果服务器收到另一个由对称算法(如 HS256)所签名的令牌,则库中的通用方法verify()会将原本的公钥视为 HMAC 密钥。这意味着,攻击者可以使用 “HS256算法 + 公钥” 对令牌进行签名,而服务器将会使用相同的公钥来验证该签名。

(译者加:

  • 原本是 “私钥签名 + 公钥验证”(非对称算法 两个密钥)
  • 然后变成了 “(HS256公钥加密) + (HS256公钥解密)”(变成对称算法 就一个公钥) )

笔记

这个对令牌进行签名的公钥,必须与服务器上存储的公钥完全相同。需要包括相同的格式(如 X.509 PEM)并保留任何非打印字符(如换行符)。在实践中,你可能需要多次尝试不同的格式,才能使此攻击生效。

# 4实现算法混淆攻击

算法混淆攻击通常涉及以下高级步骤:

  1. 获取服务器的公钥
  2. 将公钥转换为合适的格式
  3. 生成一个恶意 JWT,修改其有效信息一栏,并且alg标头设置为HS256。
  4. 使用 HS256 对令牌进行签名,将公钥作为密钥。

在本节中,我们将更详细地介绍此过程,演示如何使用 Burp Suite 执行此类攻击。

# 4.1步骤1-获取服务器的公钥

有时,服务器会映射标准端点/jwks.json或/.well-known/jwks.json,将公钥作为一个 JSON Web Key(JWK)对象进行公开。这些公钥存储在一个称为keys的 JWKs 数组中,称为 JWK Set(JWK 集合)。

{
    "keys": [
        {
            "kty": "RSA",
            "e": "AQAB",
            "kid": "75d0ef47-af89-47a9-9061-7c02a610d5ab",
            "n": "o-yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9mk6GPM9gNN4Y_qTVX67WhsN3JvaFYw-fhvsWQ"
        },
        {
            "kty": "RSA",
            "e": "AQAB",
            "kid": "d8fDFo-fS9-faS14a9-ASf99sa-7c1Ad5abA",
            "n": "fc3f-yy1wpYmffgXBxhAUJzHql79gNNQ_cb33HocCuJolwDqmk6GPM4Y_qTVX67WhsN3JvaFYw-dfg6DH-asAScw"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

即使公钥没有被公开,你也可以从一对现有的 JWTs 中提取它 (opens new window)。

# 4.2步骤2-将公钥转换为合适的格式

虽然服务器会以 JWK 格式公开其公钥,但在验证令牌的签名时,服务器会使用本地文件系统 或 数据库中存储的密钥副本。在这些数据存储系统中,公钥可能会以不同的格式进行存储。

为了攻击顺利,用来对 JWT 进行签名的公钥 必须 与服务器的本地副本相同。除了采用相同的存储格式以外,公钥的每个字节都必须相匹配,包括任何非打印字符。

在本例中,假设我们需要 X.509 PEM 格式的公钥。你可以使用 Burp 中的 JWT Editor (opens new window) 扩展将 JWK 转换为 PEM 格式,过程如下:

  1. 加载扩展程序后,从 Burp 的主选项卡转到 “JWT Editor Keys” 选项卡。
  2. 单击 “New RSA Key”。在对话框中,粘贴你之前获得的 JWK。
  3. 单击 “PEM” 按钮并复制生成的 PEM 密钥。
  4. 转到 “Decoder” 选项卡并对 PEM 进行 Base64 编码。
  5. 返回到 “JWT Editor Keys” 选项卡,然后单击 “New Symmetric Key”(新建对称密钥)。
  6. 在对话框中,单击 “Generate” 以 JWK 格式生成新密钥。
  7. 复制第四步中经过 Base64 编码的 PEM 密钥,用其替换k参数的值。
  8. 保存密钥。

# 4.3步骤3-修改你的JWT

当你有了合适格式的公钥之后,只需将alg标头设置为HS256,你就可以随心所欲地修改 JWT (opens new window)。

# 4.4步骤4-使用公钥对JWT进行签名

使用 HS256 算法对令牌进行签名 (opens new window),并将 RSA 公钥作为本次的密钥。

实验室-专家

通过算法混淆绕过JWT身份验证 >>

- name: 实验室-专家
  desc: 通过算法混淆绕过JWT身份验证 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/jwt/algorithm-confusion/lab-jwt-authentication-bypass-via-algorithm-confusion
  bgColor: '#001350'
  textColor: '#d112fe'
1
2
3
4
5
6

# 5从现有令牌中导出公钥

在公钥不容易获得的情况下,你也许可以从一对现有的 JWTs 中推导出公钥,然后测试算法混淆。使用jwt_forgery.py等工具可以让此过程变得相对简单。你可以在rsa_sign2n的 GitHub 存储库 (opens new window)中找到它,其中还包含其他一些有用的脚本。

我们还创建了此工具的简化版本,你可以将其作为单个命令来运行:

docker run --rm -it portswigger/sig2n <token1> <token2> 
1

笔记

你需要使用 Docker CLI 来运行这个工具。首次运行此命令时,它会自动从 Docker Hub 拉取镜像,这可能需要几分钟的时间。

该工具会使用你提供的 JWTs 来计算一个或多个潜在的值n。不要太关心 “n” 指的是什么 - 你只需要知道,其中只有一个n值会与服务器上的公钥相匹配。对于每个潜在值,我们的脚本都会输出:

  • 两个经过 Base64 编码的 PEM 公钥,分别采用 X.509 和 PKCS1 格式。
  • 两个伪造的 JWT 签名,分别使用每个公钥生成。

若想要识别正确的密钥,请在请求中包含每个伪造的 JWTs,并依次使用 Burp Repeater 发送,服务器只会接受其中的某一个请求。然后,你可以使用匹配公钥来构造算法混淆攻击。

实验室-专家

通过算法混淆绕过JWT身份验证-无公开的密钥 >>

- name: 实验室-专家
  desc: 通过算法混淆绕过JWT身份验证-无公开的密钥 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/jwt/algorithm-confusion/lab-jwt-authentication-bypass-via-algorithm-confusion-with-no-exposed-key
  bgColor: '#001350'
  textColor: '#d112fe'
1
2
3
4
5
6

有关此攻击过程、以及如何规范使用jwt_forgery.py工具的详细信息,请参阅存储库 (opens new window)中提供的文档。

学习更多

更多的实验室,请查看我们关于 “JWT 攻击” 主题的其余部分。

JWT 攻击 (opens new window)

编辑 (opens new window)
JWT攻击
原型链污染

← JWT攻击 原型链污染→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式