JWT简介

JWT(英文全称:JSON Web Token)是一种无状态的认证机制,通常用于授权和信息交换,是目前最主流的跨域认证解决方案

加密后的token以’.’分割,分为三部分,头部(Header)、载荷(Payload)、签名(Signature)

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30

Header原文,提供关于JWT构建方式的信息,至少指定生成签名的方式

Payload原文,令牌携带的认证信息,如用户ID或权限等级

Signature原文,用来验证JWT的完整性和安全性的签名,由头部指定的方法生成的

JWT的漏洞成因

从安全角度来看,jwt的认证机制存在几个潜在问题:

  1. 缺乏机密性,我们可以轻松解码Payload和Header内容
  2. 算法更改,改为None跳过算法校验,或改为更好操作的算法
  3. 直接删除Signature,使签名失效
  4. 暴力破解,获取密钥
  5. 密钥泄露

JWT漏洞攻击思路

找到需要JWT鉴权访问的界面,进行请求包重放测试

  1. 未授权访问:删除Token后仍然可以正常响应对应界面
  2. 敏感信息泄露:通过JWT.io解密出Payload后查看其中是否包含敏感信息,如弱密码等
  3. 破解密钥+越权访问:通过JWT.io解密Payload内容,将算法改为None或爆破密钥实现重新签发Token并修改Payload内容,进行数据包重放
  4. Payload结合其他漏洞等:修改Payload,查看是否可以结合其他如SQL漏洞,目录穿越等漏洞进行攻击

JWT相关工具

jwt-tool

安装路径及使用说明:https://github.com/ticarpi/jwt_tool

Burp Suite插件

在Extensions模块BApp Store中搜索JSON Web Tokens,安装JSON Web Tokens和JSON Web Token Attacker

插件能识别使用JWT验证的网页,并标蓝

将抓取的数据包,发送Repeater模块,能看到解密后的Tokens信息,还会提供一些攻击手段,可以对收据包进行修改重放

JWT靶场

推荐个JWT的靶场:https://authlab.digi.ninja/

Leaky JWT

获得了一个JWT认证token,我们到JWT.io查看一下,都包含哪些信息

直接获得了用户名joe,密码为MD5加密,找个在线网站解密为Password1

用获得的用户名密码就能登录成功

JWT None Algorithm

打开关卡,点击Validate Token,开启Burp Suite抓包,获取Token

数据包发送Repeater,在JWS下查看,选择将签名移除

回到Header中查看,alg已经变为None,在Payload中修改用户weibob33,重发,并成功登录

User Agents

先使用admin/admin进行登录,发现没有反应

查看页面信息,让我们下载一个文件,并对其内容进行分析

查看代码,内容很简单,当User-Agent内容为authlab desktop app时,返回一些信息

我们抓包,修改User-Agent内容为authlab desktop app,提交,得到新的信息

不要怀疑自己,到这确实就结束了,也许靶场作者想要告诉开发者们,即使是非基于网页的应用程序,哪怕是本地桌面程序也要使用正确的会话管理或身份管理

CTF题目

CTFHub

CTFHub是通过消耗金币进行训练的CTF网站,金币通过签到和解题获得,地址:https://www.ctfhub.com/#/index

敏感信息泄露

打开解题环境,admin/admin登录

抓包看到JWT相关Token

复制到JWT.io,看到了flag

1
ctfhub{218c08b7ae29c28aeab02a92}

无签名

打开解题环境,依旧admin/admin登录,查看信息

抓包看一下获得JWT Token,到JWT.io解一下

提示只有admin权限才能查看,本关名为无签名,那就在Burp Suite尝试修改签名,发到Repeater修改签名,进行重放

以’.’为分割,将Header中的算法改为none

将Payload中的role修改为admin

重新拼接,并删除签名部分

提交,获得flag

1
ctfhub{eb11c0b0d5d32807bd90cdf9}

修改签名算法

打开解题环境,老规矩admin/admin登录,看到密钥文件,注意:要下载整个页面,不然会出错,获取密钥

网上找了一份python代码文件,在已知密钥的情况,可以对payload进行修改,生成新的Token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#coding=utf-8

import hmac
import hashlib
import base64

file = open('publickey.pem') #需要将文中的publickey下载 与脚本同目录
key = file.read()

#Paste your header and payload here

header = '{"typ": "JWT", "alg": "HS256"}'
payload = '{"username": "admin", "role": "admin"}'

#Creating encoded header

encodeHBytes = base64.urlsafe_b64encode(header.encode("utf-8"))
encodeHeader = str(encodeHBytes, "utf-8").rstrip("=")

#Creating encoded payload

encodePBytes = base64.urlsafe_b64encode(payload.encode("utf-8"))
encodePayload = str(encodePBytes, "utf-8").rstrip("=")

#Concatenating header and payload

token = (encodeHeader + "." + encodePayload)

#Creating signature

sig = base64.urlsafe_b64encode(hmac.new(bytes(key, "UTF-8"), token.encode("utf-8"), hashlib.sha256).digest()).decode("UTF-8").rstrip("=")

print(token + "." + sig)

将密钥存入publickey.pem,与代码文件放在同一级目录

运行代码文件,获得新的Token

抓包,用新的token进行覆盖,重放获得flag

1
ctfhub{a3984c0a492897d91de2bcf9}