SpringForwardCTF2024 web

Socratic-Script

上传发现弹窗
image.png
image.png
禁用js就行了
把题目给的附件txt上传就行了
image.png

Into-the-Gorgons’-Den

看源码
image.png
得到第三部分flag:_g0rg0n}
image.png
第一个框的按钮调用的是mirror()方法,跟进一下
image.png
输入suesrep返回Medusa's weakness is her reflection! She will turn her gaze at the 30th minute minus 2.美杜莎的弱点是她的倒影!她将把目光转向第 30 分钟减去 2。
等到28分
1714369463656.jpg
页面下面有段密文image.png
image.png
这句话的意思是第二部分的flag是th3
最终
nicc{sl4y_th3_g0rg0n}

back-in-time

进去一登录框
image.png
有注入
直接 admin 1"or"1"="1 就登进去了
查看源码得到<!-- back-in-time flag part 1 of 3: "nicc{nBUE2hG" -->
/[travel](http://34.207.63.151/travel)路由源码得到 <!-- back-in-time flag part 2 of 3: "meTQRbL" -->
访问/status路由时
image.png
nicc{nBUE2hGmeTQRbLcijueiF}

Underworld-Bypass

描述:

Cast into the inferno’s depths, souls languish in perpetual torment, with no reprieve from the hellfire’s embrace. Yet whispers endure of a realm_key, a legendary artifact able to traverse the boundaries between worlds, offering a glimmer of salvation. The question that burns as fiercely as the flames themselves: do you possess the courage to seek it? Find flag.txt and submit the flag in the format flag nicc{flag}

flag在flag.txt
hint:The Keeper's Riddle last line
image.png
发现文件读取
/explore.php?file=/realm_key/flag.txt
image.png

back-in-time-2-electric-boogaloo

给了源码
/routes/travel.js找到了flag
image.png

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { sqlConnection } from '../app.js';
import timeController from '../system-control.js';
import { Router } from 'express';

const timeTravelRouter = Router({ mergeParams: true });

timeTravelRouter.get('/', async (req, res) => {
let results;

try {
[results] = await sqlConnection.execute(
'SELECT * FROM leaps ORDER BY leap_id DESC');
} catch (error) {
results = null;
}


let lastTravelDate;
if (results && results.length) {
const lastTravelEntry = results[0];
lastTravelDate = new Date(lastTravelEntry.leap_date);
lastTravelDate.setFullYear(lastTravelEntry.year);
} else {
lastTravelDate = new Date('1970-01-01');
}

res.render('travel', {
session: req.session,
currentDate: new Date(),
lastTravelDate: lastTravelDate,
destinationDate: timeController({ type: 'GetSetpoint' }),
});
});

timeTravelRouter.put('/', async (req, res) => {
const request = { type: 'SetSetpoint' };

if (req.body.debug && !(process.env.ALLOW_USER_DEBUG === 'true')) {
return res.json({ error: 'Debug mode is not allowed to be set.' });
}

for (const prop in req.body) {
request[prop] = req.body[prop];
}

const date = new Date(req.body.date);
let year = req.body.year;
if (req.body.bc)
year = year * -1;
date.setFullYear(year);
try {
timeController(request);
if (request.debug) {
return res.json({ success: true, debugInfo: process.env.FLAG });
} else {
return res.json({ success: true });
}
} catch (err) {
res.status(500);
if (request.debug) {
return res.json({ error: err.message, debugInfo: process.env.FLAG });
} else {
return res.json({ error: err.message });
}
}

});
timeTravelRouter.post('/', async (_req, res) => {
try {
timeController({ type: 'TimeTravel' });
return res.json({ success: true });
} catch (err) {
res.status(500);
return res.json({ error: err.message });
}
});

export default timeTravelRouter;

1
2
3
4
5
if (request.debug) {
return res.json({ success: true, debugInfo: process.env.FLAG });
} else {
return res.json({ success: true });
}

request.debug==true就返回flag 看上去能用原型链污染
在web页面登录后(和第一题一样登录)
image.png
image.png
加上debug参数
image.png
这里触发了

1
2
3
if (req.body.debug && !(process.env.ALLOW_USER_DEBUG === 'true')) {
return res.json({ error: 'Debug mode is not allowed to be set.' });
}

接着下一行

1
2
3
for (const prop in req.body) {
request[prop] = req.body[prop];
}

把请求的属性和值都给了request对象,包括原型链上的属性
传入

1
2
3
4
5
6
7
8
{ 
"date": "2024-04-27",
"year": "1945",
"bc": true ,
"__proto__": {
"debug": true
}
}

if (req.body.debug && !(process.env.ALLOW_USER_DEBUG === 'true'))时不会读取原型链__proto__属性,所以这里req.body.debug不为true,绕过了if
而接着经过for (const prop in req.body)的遍历
读取了原型链__proto__属性并给了request对象,所以if (request.debug)为true,返回flag
image.png


SpringForwardCTF2024 web
http://example.com/2024/04/28/SpringForwardCTF2024web/
作者
J_0k3r
发布于
2024年4月28日
许可协议
BY J_0K3R