2025N1CTF WP
2025N1CTF WP
WEB
eezzjs
审计代码,程序主要做了一个登录的jwt的检验
程序里面的admin_password和secret的值都是随机的字节,并且没有register的功能,因此我们没有办法拿到任何的token,只能自己伪造。
再审计代码可以看到在auth.js的verifyJWT函数中,计算sha256的时候往hash里面传入的payload是一个object的值
1 | const expectedSignatureHex = sha256(...[JSON.stringify(header), payload, secret]); |
sha256函数则是将传入的值全部update进hash,然后再对其进行加密计算
1 | const sha256 = (...messages) => { |
这个时候我们去找update的源码
1 | Hash.prototype.update = function (data, enc) { |
可以看到,当传入update的为非string值时,仍然会有一个取data.length并加入this._len的过程,那么当我们修改传入的data的length的值,就可以影响前后传入的变量后的结果,如果所有的参数传输完毕后,若this._len=0,那么最终hash.digest()的结果就会是一个固定的值。
那么观察secret的生成规则
1 | const JWT_SECRET = crypto.randomBytes(9).toString('hex'); |
可以注意到secret是一个18字节的字符串,那只要在sha256函数传入secret之前将this._len设置为-18,后面加上secret之后sha256的返回结果就是固定可知的。
调用signJWT函数伪造JWT
1 | const header = { alg: 'HS256', typ: 'JWT' }; |
此时,sha256在传入header,payload,secret后最终返回的结果将会固定为674dcdbbb09261235ee8efc1999daee725dad0ec314a8d1d80cb11229e7596c1
此时修改token=674dcdbbb09261235ee8efc1999daee725dad0ec314a8d1d80cb11229e7596c1,访问/upload即可绕过verifyJWT
其实这是一个新鲜的CVE漏洞CVE-2025-9288
漏洞核心:输入类型检查缺失引发的加密灾难
漏洞点在的JavaScript加密库sha.js@2.4.5–2.4.11及 sha.js@3.2.4–3.2.8
攻击者可实现的四类危害:
哈希状态回滚
输入
{ length: -x }类参数可回滚内部状态,将标记哈希(用于数据完整性保护)降级为未标记哈希,破坏加密机制。数值误算与碰撞
构造
{ length: buf.length, ...buf, 0: buf[0] + 256 }使不同数值生成相同哈希,引发逻辑不一致(如与bn.js交互时)。拒绝服务(DoS)攻击
输入
{ length: '1e99' }导致函数无限挂起,服务资源耗尽。私钥提取(最严重后果)
在依赖哈希生成随机数的系统(如非对称加密)中,匹配哈希值但数值解释差异可导致私钥被推导恢复。