女娲补胎⚓︎
约 604 个字 43 行代码 预计阅读时间 3 分钟
解题过程⚓︎
首先看到其给出的提示,说此题是简单题,只需要仔细阅读代码便可以完成。在浏览了整个项目的结构和内容后,着重看了看 service/start.sh
和 src/app.js
这两个文件。我大概已经了解了这个题目的大致思路。
成功登录⚓︎
一眼看过去,我们要做到成功登录,就是要拿到正确的 admin_key
,用户名和密码。app.js
中的相关函数如下:
//归墟哈希
function Gui_Xu(str) {
const hash = Tong_Que.createHash('md5');
hash.update(str);
return hash.digest('hex');
}
//神兽「玄武」以甲壳御侮、以鳞角擅战
function Xuan_Wu(req) {
if (req.header['admin_key'] != undefined)
if (Gui_Xu(req.header['admin_key']) == "81cb271f0e52999ba6a0fb11fa6dd9fd")
return "pass"; return "fail";
}
zhu_Rong.post('/', (req, res) => {
const { username, password } = req.body;
if (username === 'admin' && password === He_Tu) {
res.cookie('role', 'user', {
httpOnly: true,
maxAge: 3600000,
sameSite: 'strict'
});
req.session.user = username;
req.session.logined = "true";
return res.redirect('/flag');
}
req.session.error = '登录失败';
res.redirect('/');
});
# 咳咳咳
# 河图密码好像不够安全
# 还是换一个吧
sed -i "s/12345678910/$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)/" /app/app.js
chmod 740 /app/*
node app.js
admin_key⚓︎
这玩意确实让我迷糊了一下,在没仔细阅读代码的情形下,我先去找了 cmd5
去反解这个 md5
值,结果发现查不出来。于是再仔细一看,发现玄武函数中当前的 return
语句存在逻辑错误。由于 return "pass";
后面没有使用大括号 {}
包裹的代码块,return "fail"
总是会被执行,无论前面的条件是否成立。因此,无论条件如何判断,函数总会返回 fail
。而且事实上,这一项和后面的验证也没什么关系,因此我们可以直接忽略掉。
用户名⚓︎
用户名就比较清晰了,就是 admin
。
密码⚓︎
对于密码的获取,我则绕了一圈弯路,表面是它是固定常量 12345678910
,但是 start.sh
中的 sed
命令会将 12345678910
替换为一个随机密码,并且这个随机密码会被存储在 app.js
中的 He_Tu
变量中,而我们现在就是要拿到这个随机密码。作为小白,本着什么工具都试试的精神,用 burpsuite 一顿分析,结果帮助为 0。最终想起了提示中提到的仔细阅读代码,于是我又回到了 app.js
中去仔细看了一圈,结果就在开头我便看到了关键之处。
!这就是关键所在了!这行代码的意思是将 static
中的文件暴露在 /
路径下。也就是说,我们可以直接通过 /app.js
来访问这个文件,从而获取到其中被替换的密码。
至此,我们已经可以成功登录了。
替换 cookie⚓︎
在源码中,我们可以看到的一个比较大的洞是:
在之前我们已经知道了成功登录后 role
的值是 user
,而我们只需要将其替换为 admin
,然后直接访问 /flag
,即可拿到 flag 为 0ops{x66ZTwpe5fbrJuD69SrAuA}
。
评论区