[SCTF2020] CloudDisk 当前位置: Home » Linux,CTF,Docker » [SCTF2020] CloudDisk ~~又来水文章了~~ 十几天前的比赛,今天没blog写,来复现下web签到题。 --- clone官方wp&docker环境 ```bash docker build -t sctf/clouddisk . docker run -d -p 8090:3333 2f2 ``` - 使用当前目录的dockerfile提取镜像,tag叫做sctf/clouddisk - 后台创建新容器并制定映射端口为8090  +上题目给的一段源码: ```javascript const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const Koa = require('koa'); const Router = require('koa-router'); const koaBody = require('koa-body'); const send = require('koa-send'); const app = new Koa(); const router = new Router(); const SECRET = xx app.use(koaBody({ multipart: true, formidable: { maxFileSize: 2000 * 1024 * 1024 } })); router.post('/uploadfile', async (ctx, next) => { const file = ctx.request.body.files.file; if (!fs.existsSync(file.path)) { return ctx.body = "Error"; } if(file.path.toString().search("/dev/fd") != -1){ file.path="/dev/null" } const reader = fs.createReadStream(file.path); let fileId = crypto.createHash('md5').update(file.name + Date.now() + SECRET).digest("hex"); let filePath = path.join(__dirname, 'upload/') + fileId const upStream = fs.createWriteStream(filePath); reader.pipe(upStream) return ctx.body = "Upload success ~, your fileId is here:" + fileId; }); router.get('/downloadfile/:fileId', async (ctx, next) => { let fileId = ctx.params.fileId; ctx.attachment(fileId); try { await send(ctx, fileId, { root: __dirname + '/upload' }); }catch(e){ return ctx.body = "SCTF{no_such_file_~}" } }); router.get('/', async (ctx, next) => { ctx.response.type = 'html'; ctx.response.body = fs.createReadStream('index.html'); }); app.use(router.routes()); app.listen(3333, () => { console.log('This server is running at port 3333.') }) ``` --- 当时做的时候通过万能的google搜到了这样一个issue: [https://github.com/dlau/koa-body/issues/75](https://github.com/dlau/koa-body/issues/75) 然后直接exp打出的flag。现在来康康。 emmm~ 虚拟机的node环境搞了一个多小时没搞好,现在都1:24了,狗命要紧。就不深入了。 在issues中写的已经很明白了: > Suppose you have JSON body parsing enabled on a POST or PUT route, say '/upload-files', as well as multipart parsing. This is quite easy to do e.g. if you add JSON parsing as global middleware. Suppose it expects the files to be in a field named 'uploads'. Then you can make a POST or PUT request to '/upload-files' with a JSON body that looks something like {"files": {"uploads": [{"path": "/any/file/path"}]}}, making the request handler think a file has been uploaded to /any/file/path. Now suppose that the handler is set up to copy uploaded files into a public uploads folder. By choosing the path appropriately I can make the server copy any file I like on the server into the public uploads folder and then view its contents. So by using well-known paths of sensitive files I can read private keys, passwords etc. and maybe even gain full access to the server this way. 大概意思就是说如果向文件上传的路由如:/uplaod上传json主体的格式,那么其中path将被解析成已经上传完的文件位置保存到相应文件中。 `poc:{"files":{"file":{"name":"xiaoyue","path":"/etc/passwd"}}}`  这样直接catflag也就行了。 ```bash {"files":{"file":{"name":"xiaoyue","path":"flag"}}} ``` emm~
Comments | NOTHING