Rating:

首先题目给了源码,uploadfile的处理逻辑如下:
```javascript=
router.post('/uploadfile', async (ctx, next) => {
const file = ctx.request.body.files.file;
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;
});
```
审计一会儿会发现从 `ctx.request.body` 取文件对象用的是koa-body的老版本的写法,于是我写了一个demo,把每个请求的 `ctx.request.body` 给打印出来,我们会发现对于文件对象,koa-body2.x版本会处理成这样的格式
![](https://i.loli.net/2020/07/08/nKrYWl9FkvjIeLH.png)
就像和post一条json一样
再参考这条issue
`https://github.com/dlau/koa-body/issues/75`
我们就能轻松构造出payload
```
{"files":{"file":{"path":"/proc/self/cwd/flag","name":"1"}}}
```
![](https://i.loli.net/2020/07/08/XrAVlvMJipctOzx.png)

![](https://i.loli.net/2020/07/08/7sO4lkLSB3v5KaW.png)