jwt学习
0x00 背景
起因:刷题的过程中看见一道题写着kunkun应援团,有应援口号,并集资11540必须买lv6?
滋滋滋,干就完事。
注册了账号,去购物车翻找lv6的商品,由于页数过多,用了个小脚本找到了lv6的商品在181页
脚本
from urllib import request |
抓包修改一波价格
修改失败,提示操作失败,但发现有一次返回为302,并附带一个目录,访问后发现只允许admin访问
并且包中发现网站是通过JWT进行身份验证。无奈想请教一波大佬,结果大佬忙,只得自己研究一波JWT。。。
0x00 JWT基础
百度介绍JWT是Json Web Token的缩写,主要用于验证用户身份信息及跨域的身份验证。
而JWT一般是由三部分组成,并使用base64编码组成
以下为完整的JWT认证信息。 |
Header(标头)
标头通常由两部分组成:令牌的类型和所使用的签名算法,例如HMACSHA256或RSA
|
Payload(有效载荷)
主体信息(有效载荷),其中包含声明,声明是有关实体(一般是用户)和其他数据的声明。索赔有以下三种类型:
注册的,公共的和私人权利
已注册的权利要求:
这些是一组非强制性的但建议使用的预定义权利要求,以提供一组有用的可互操作的权利要求。其中一些是: iss(主题), exp(到期时间), sub(主题), aud(受众)等。
公开声明:
使用JWT的人员可以随意定义这些声明。但为避免冲突,应在IANA JSON Web令牌注册表中定义它们,或将其定义为包含抗冲突名称空间的URI。
私人权利:
这些都是使用它们同意并既不是当事人之间建立共享信息的自定义声明注册或公众的权利要求。
官方规定的七个字段(不强制要求选择,也可以自定义字段)
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
payload = '{ |
Signature(签名)
签名,要创建签名部分,您必须获取编码的标头,编码的有效载荷,机密,标头中指定的算法,并对其进行签名。
如果要使用HMAC SHA256算法,则将通过以下方式创建签名
HMACSHA256( |
Python生成jwt web token
import time |
生成的token
eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1OTUwNzM1NDguNjcyNzk2LCJuYW1lIjoiYWRtaW4ifQ.m_f32qmeuFTCugdPBfMA1jGmpkXWoI3Vjt-sY30_xrw |
Python解密JWT
import jwt |
解密内容
{'iat': 1595073548.672796, 'name': 'admin'} |
0x01 攻击手法
敏感信息泄露
因header和payload部分是使用可逆的base64方法编码,所以只要获取到令牌就可以将前两个部分解密后读取内容。
解密方法
Linux base64 |
修改签名算法(none)
JWT签名算法可确保JWT在传输过程中不会被恶意用户所篡改,但头部的alg字段可以改为none,若服务器支持签名算法为none,服务器会在JWT中删除相应的签名数据(这时,JWT就会只含有头部 + ‘.’ + 有效载荷 + ‘.’),然后将其提交给服务器。
源码:https://github.com/Sjord/jwtdemo |
发送上面的JWT令牌
将alg修改为none
import time |
修改RS256算法为HS256
HS256算法使用密钥为所有消息进行签名和验证,而RS256算法则使用私钥对消息进行签名并使用公钥进行身份验证。如果将算法从RS256改为HS256,则后端代码将使用公钥作为密钥,然后使用HS256算法验证签名。由于攻击者有时可以获取公钥,因此,攻击者可以将头部中的算法修改为HS256,然后使用RSA公钥对数据进行签名。这样的话,后端代码使用RSA公钥+HS256算法进行签名验证。
demo:http://demo.sjoerdlangkemper.nl/jwtdemo/rs256.php |
获取网站公钥,将算法改为HS256然后使用泄露的公钥进行签名,服务器会使用HS256和泄露的公钥进行验证。
import jwt |
破解HS256密钥
如果HS256密钥的强度较弱的话,攻击者可以直接通过蛮力攻击方式来破解密钥,例如将密钥字符串用作PyJWT库示例代码中的密钥的时候情况就是如此。
安装pyjwt |
0x02 攻防世界9分题-bilibili
了解了一波JWT,继续完成我们的kunkun集资应援,之前我们获得了一串JWT加密信息如下
JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRpbWUifQ.2YosC1XgEHYbLonkRpX49gi3Lqnr4dngsThwnBGvhwA |
去jwt.io解密,将username中的Time改成admin,重新生成密文
报错500,失败,使用py脚本尝试爆破秘钥
使用上面给出的脚本即可,成功爆出秘钥为1Kun。
在jwt.io重新生成秘钥后,替换当前JWT密文
替换重新生成的JWT后,成功访问到admin页面
一番查找后发现网页源代码中有网站源码
下载后发现是使用python编写的网站源码。。。。莫不是要做python的代码审计????
9分题果然不是我等菜鸟能做出来的,只能祭出Writeup大法,看看python是如何审计的。
我一看wp就发现大佬直接扔出来了一个脚本跑flag。
flag脚本
import pickle |
成功,但我是不会让大家知道我做此题花费多长时间
0x03 JWT CTF练习
练习地址: |
JSON Web Token (JWT) - Introduction
题目: |
尝试登陆抓包,没有获取到任何有用信息,发现登陆框有个黄色的login as guest,点击抓包放包后返回一串JWT令牌信息
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0In0.OnuZnYMdetcg7AWGV6WURn8CFSfas6AQej4V9M13nsk |
去jwt.io网站解密
发现有效载荷的用户是guest,所以尝试一波改成admin能行不,但如果修改用户为admin,需要重新生成一下令牌,而现在不知道密钥,可以尝试爆破一波,看看是否能爆破出来。没有爆出来,就有点难受了。。。
尝试修改签名算法,由于jwt.io不支持none算法,所以使用python生成
import jwt |
flag : S1gn4tuR3_v3r1f1c4t10N_1S_1MP0Rt4n7 |
RootMe的JSON Web Token (JWT) - Weak secret
题目:http://challenge01.root-me.org/web-serveur/ch59/hello |
打开网站后得到一段提示
网翻后。。
先访问/token
得到令牌
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiZ3Vlc3QifQ.4kBPNf7Y6BrtP-Y3A-vQXPY9jAh_d0E6L4IUjL65CvmEjgdTZyr2ag-TM-glH6EYKGgO3dBYbhblaPQsbeClcw |
然后使用post方式访问/admin
添加Authorization: Bearer YOURTOKEN字段 |
提示爆破。。。
成功 key是lol
然后去jwt.io生成令牌
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJyb2xlIjoiYWRtaW4ifQ.y9GHxQbH70x_S8F_VPAjra_S-nQ9MsRnuvwWFGoIyKXKk8xCcMpYljN190KcV1qV6qLFTNrvg4Gwyv29OCjAWA |
flag: PleaseUseAStrongSecretNextTime |
RootMe JSON Web Token (JWT) - Public key
题目: |
首先查看key,貌似很熟悉,就是我们刚刚说过的修改RS256为HS256算法,直接上脚本
然后使用post方式访问/auth
提示需要添加username字段
成功获取token
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6InRpbWUifQ.AWLoeQgDwlTs5q2_32D0rjfKjDJXmUo6r31VVireLpuWaIo3y_xJFHXAGeDhP9l2f1TSDDLO-5o-vIp3Fb9zacQUIw4ZdBcFxSobbHHYxsxuaMhH4kVsgWU1Pg5DRAgufA3c-evuq54byYWWRMgod4P-icMZxkJ1vLxCget5xLIE62qyFBkG4nK6oszmg_wkzK-O5PMUtC_eitO9PAVdR-2JcSSV8tSITEmoBzAK90RGqKQ1sBbm29xtStkZr2TsNo1NT2lrnzaROCO46uQEC7RWbA6kf37oZOF2JOVKQLTnHsobXKPrtKs7MvLwjXkJ1rM3mpvv9ZAE2ePJ7ByBpQ |
RS256算法
脚本
import jwt |
访问/admin目录使用post方式添加内容到cookie中
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.qZzbNQNfGLSyuvwhb1mKJhBnr3tFHJriIMuxzNEYoG0 |
flag : HardcodeYourAlgoBro |
0x04 参考链接
https://www.jianshu.com/p/c5f2a4e1c98d
http://sircoding.club/blog/post/sirc0de/JWT
http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
https://blog.csdn.net/weixin_44604541/article/details/108921381