558 字
3 分钟
ctfshow-jwt学习
2024-07-29

web345#

把cookie扔到 https://jwt.io/ 解密

头和payload,且头无加密方式

所以直接将payload的sub值改为admin就行

发包时发现带头部的话得不到flag

![[d8c7b7cd74ac3d1a857371b8ca8e7abb_MD5.jpg]]

尝试只发payload却成功,没搞懂 /_ \

web346#

将header里的alg改为none,这样绕过加密方式(也可以直接爆密钥)

payload后加一.

web347#

爆破!

佬的脚本,注意使用时不能将文件名命名为jwt.py,并且使用前要

pip install jwt
pip install PyJWT

然后随便找个密码本破就行,注意在win环境下复制的文件路径的\要换为/
字典:https://github.com/danielmiessler/SecLists

import jwt

token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcxMTM3NTcxNCwiZXhwIjoxNzExMzgyOTE0LCJuYmYiOjE3MTEzNzU3MTQsInN1YiI6InVzZXIiLCJqdGkiOiJjYzU4ZGUyOTkyMGZiNDY2Y2FiZWE0Y2E2YWZkNzEyZSJ9.LEVCHMoALD0ENPHLjTw7QeXxgrCVANvCZaydE5ehGsk" # 题目中的 token
password_file = "H:/tOOLS/DIR/PasswordDic/弱口令字典/passwd-CN-Top10000.txt" # 密码文件

with open(password_file,'rb') as file:
    for line in file:
        line = line.strip() # 去除每行后面的换行
        try:
            jwt.decode(token, verify=True, key=line, algorithms="HS256") # 设置编码方式为 HS256
            print('key: ', line.decode('ascii'))
            break
        except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError
                , jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError,
                jwt.exceptions.ImmatureSignatureError): # 出现这些错误,虽然表示过期之类的错误,但是密钥是正确的
            print("key: ", line.decode('ascii'))
            break
        except jwt.exceptions.InvalidSignatureError: # 签名错误则表示密钥不正确
            print("Failed: ", line.decode('ascii'))
            continue
    else:
        print("Not Found.")

![[f2c862987be50b60ae8543f640245810_MD5.jpg]]

另一种方法,使用jwt-cracker
https://github.com/brendan-rius/c-jwt-cracker

用docker的方式老是报错,所以clone到本地
我是用的是kali,记得apt-get install libssl-dev

等了好久没结果,最后还是用脚本了

将密码填入
![[d34cead8953643f35cd91d4f5ce70859_MD5.jpg]]
复制发包访问/admin/

web348#

还是爆破,用脚本跑字典,得到

![[6beb6f2fed7d444097e95bc4c7e41b1b_MD5.jpg]]

用cracker的话:

![[9406e82550f9a536e72923115b160e75_MD5.jpg]]

web349#

给了个这

/* GET home page. */
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');
	  }
	});
});

发现公私钥都在public目录下,那么访问后会下载

![[11c66cab33b45e9e1770983ead966a83_MD5.jpg]]

https://www.bejson.com/jwt/ 里填入公私钥
![[0ae3ce0fb9a10cccdd64400a1e279ea5_MD5.jpg]]

编码后替换cookie发包

web350#

在源码内发现公钥

![[5d36629b1ab4ae8cdabf778428b66b3c_MD5.jpg]]

RS256HS256
RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。公钥即使泄漏也毫无影响,只要确保私钥安全就行。HS256 使用同一个「secret_key」进行签名与验证(对称加密)。一旦 secret_key 泄漏,就毫无安全性可言了。

我们只发现了公钥,尝试将加密方式改为HS256

ctfshow-jwt学习
http://orxiain.life/posts/ctfshow-jwt学习/
作者
𝚘𝚛𝚡𝚒𝚊𝚒𝚗.
发布于
2024-07-29
许可协议
CC BY-NC-SA 4.0