什么是JWT
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA—[摘自官网]
http://jwt.io
翻译: jsonwebtoken(JWT)是一个开放标准(rfc7519),它定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任,因为它是数字签名的。jwt可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名
通俗解释:JWT简称JSON Web Token,也就是通过JSON形式作为Web应用中的令牌,用户在各方之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。
JWT的结构
1 令牌组成
-
标头(Header)
-
有效负荷(Payload)
-
签名(Signature)
因此:JWT通常如下所示:xxxx.yyyy.zzzz Header.Payload.Signature
1.1 标头 - Header
标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。它会使用 Base64 编码组成 JWT 结构的第一部分。
**注意:**Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程。
{
"alg": "HS256",
"typ": "JWT"
}
ewogICAiYWxnIjogIkhTMjU2IiwKICAgInR5cCI6ICJKV1QiCiB9.
1.2 有效载荷 - Payload
令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。同样的,它会使用 Base64 编码组成 JWT 结构的第二部分
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"exp":时间戳
}
1.3 签名 - Signature
前面两部分都是使用 Base64 进行编码的,即前端可以解开知道里面的信息。Signature 需要使用编码后的 header和 payload以及我们提供的一个密钥,然后使用 header 中指定的签名算法(HS256)进行签名。签名的作用是保证 JWT没有被篡改过-如:
HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret)
签名目的:
最后一步签名的过程,实际上是对头部以及负载内容进行签名,防止内容被窜改。如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。
安全问题
1 敏感信息泄露
JWT保证的是数据传输过程中的完整性而不是机密性。
因为JWT的payload部分是使用Base64url编码的,所以它其实是相当于明文传输的,当payload中携带了敏感信息时,我们对payload部分进行Base64url解码,就可以读取到payload中携带的敏感信息。
随便登陆
查看此时的JWT
eyJBRyI6ImViNThjNTBkNzM2MDdkN30iLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
{"AG":"eb58c50d73607d7}","typ":"JWT","alg":"HS256"}
eyJ1c2VybmFtZSI6Inhpbmd5dW5cdCIsInBhc3N3b3JkIjoieGluZ3l1biIsIkZMIjoiY3RmaHViezdlZjFiMWY0ZCJ9
{"username":"xingyun","password":"xingyun","FL":"ctfhub{7ef1b1f4d"}
2 无签名(none算法)
一些JWT库也支持none算法,即不使用签名算法。当alg字段为空时,后端将不执行签名验证。尝试找到flag。
3 弱密钥(c-jwt-cracker爆破密钥)
如果JWT采用对称加密算法,并且密钥的强度较弱的话,攻击者可以直接通过蛮力攻击方式来破解密钥https://github.com/brendan-rius/c-jwt-cracker
sudo apt-get update
sudo apt-get install libssl-dev
make
签名部分是(HMACSHA256(base64UrlEncode(header) + “.” +base64UrlEncode(payload),secret)
如果前面的header和payload做出更改的话,签名认证也会随之更改。 同时,在使用不同的密钥对头部信息和载荷进行加密时,所产生的JWT是不一样的签名部分是(HMACSHA256(base64UrlEncode(header) + “.” +base64UrlEncode(payload),secret)
如果前面的header和payload做出更改的话,签名认证也会随之更改。 同时,在使用不同的密钥对头部信息和载荷进行加密时,所产生的JWT是不一样的
# 抓包看到了Cookie,然后访问网页将其内容进行修改
https://jwt.io/
# 使用kali对其进行破解出ulim值
得到flag。
4 修改签名算法
有些JWT库支持多种密码算法进行签名、验签。若目标使用非对称密码算法时,有时攻击者可以获取到公钥,此时可通过修改JWT头部的签名算法,将非对称密码算法改为对称密码算法,从而达到攻击者目的。ctfhub中这个题环境有问题,推荐大家使用其他靶场练习。
好小子,离成功又近一步!!!