Ivanti Sentry CVE-2026-10520: KEV Pre-Auth OS Command Injection

Suspected
Discovered Jun 11, 2026

CISA and Ivanti confirmed active exploitation of CVE-2026-10520, a critical pre-authentication OS command injection vulnerability in Ivanti Sentry. Attackers can execute arbitrary commands with root privileges by sending a crafted HTTP POST request to Sentry MICS APIs.

0
Affected Packages
0
Observables
0
Sources

Defender Action Panel

Triage this incident quickly

Check whether your environment installed affected software, copy the top IOCs, run the tested hunting script when available, then review remediation guidance.

Am I affected?
Review affected software below
Immediate action
Audit locks, CI runners, developer workstations, and credential exposure.
Hunting
Has hunting script

Analysis

Executive Summary

CVE-2026-10520 is a critical operating system command injection vulnerability in Ivanti Sentry (formerly MobileIron Sentry). An unauthenticated remote attacker can exploit the flaw by sending a specially crafted HTTP POST request to the unauthenticated Management Infrastructure Configuration Service (MICS) configuration endpoint /mics/api/v2/sentry/mics-config/handleMessage [ivanti.com opens in a new tab]. This allows the attacker to execute arbitrary OS commands on the appliance with root-level privileges [labs.watchtowr.com opens in a new tab].

The vulnerability has been observed under active exploitation in the wild. Consequently, the Cybersecurity and Infrastructure Security Agency (CISA) added it to the Known Exploited Vulnerabilities (KEV) Catalog on June 11, 2026 [cisa.gov opens in a new tab]. The vulnerability frequently appears alongside CVE-2026-10523, a critical pre-authentication bypass vulnerability (CVSS 9.9) in Sentry that allows attackers to create unauthorized administrative accounts [ivanti.com opens in a new tab].

Defenders are urged to update their Sentry appliances immediately to the patched versions: R10.5.2, R10.6.2, or R10.7.1 [ivanti.com opens in a new tab]. If immediate patching is not possible, organizations must block external access to the management port (typically 8443) and implement Web Application Firewall (WAF) or intrusion detection system rules to filter traffic to the affected /mics/api/v2/sentry/mics-config/ path [labs.watchtowr.com opens in a new tab].

Key Facts

Cve: CVE-2026-10520

Vendor: Ivanti

Component: MICS (MobileIron Configuration Service)

Vulnerability Class: OS Command Injection (CWE-78)

Severity: Critical (CVSS 10.0)

Disclosed Date: 2026-06-09

Kev Added: 2026-06-11

Affected Versions: Sentry versions prior to R10.5.2, R10.6.2, and R10.7.1

Required Action: Update Ivanti Sentry to R10.5.2, R10.6.2, or R10.7.1, restrict external management port access, and review Apache/Tomcat log telemetry.

Evidence Assessment

  • confirmed: Ivanti confirmed the OS command injection flaw and issued patches for the R10.5.2, R10.6.2, and R10.7.1 branches [ivanti.com opens in a new tab].
  • confirmed: watchTowr Labs researchers analyzed the vulnerability, demonstrating unauthenticated RCE via a POST request to /mics/api/v2/sentry/mics-config/handleMessage containing a commandexec XML payload [labs.watchtowr.com opens in a new tab].
  • confirmed: CISA added CVE-2026-10520 to the KEV Catalog on June 11, 2026, confirming active exploitation [cisa.gov opens in a new tab].
  • confirmed: The vulnerable endpoint parses the message string using StringTokenizer and passes command inputs to executeNativeCommand() [labs.watchtowr.com opens in a new tab].
  • unclear: Forensic investigations have not publicly detailed the exact malware families, payloads, or attacker groups currently exploiting Sentry gateways.

Impact Determination

Analysis table
ClassificationCriteriaRequired evidenceRequired action
Confirmed compromiseEvidence of unauthenticated POST requests targeting /mics/api/v2/sentry/mics-config/handleMessage resulting in a HTTP status 200, unexpected processes running under Tomcat user, unauthorized admin accounts, or web shells in tomcat directories.Apache access logs, Tomcat localhost access logs, audit logs, and running process list.Isolate the appliance, perform full forensics, check for credential theft, rebuild using clean firmware, and rotate all corporate credentials.
Presumed exposedThe Sentry appliance runs a version prior to R10.5.2, R10.6.2, or R10.7.1 with the management port 8443 exposed to the public internet during the exploitation window.Sentry version config, port scanning results, and Apache configuration file.Isolate the management interface immediately, apply the required patch, and run the log scan hunt script.
Potentially exposedSentry appliance versions are unknown, or the status of management interface accessibility from external IPs is not verified.Inventory data, firewalls rules, and system version logs.Enumerate Sentry gateway assets and verify access control lists on port 8443.
Not exposedThe Sentry appliance runs a patched version, or port 8443 is blocked from external networks by firewall rules.Sentry version check showing R10.5.2+, R10.6.2+, or R10.7.1+, and firewall verification.Maintain standard log audits and check for new vendor security advisories.

Minimum Evidence To Collect

  • Apache access logs (/var/log/httpd/https-access_log): These logs should be collected because they record external POST requests to /mics/api/v2/sentry/mics-config/handleMessage which resolves the initial access timeline and identifies the attacker source IP.
  • Tomcat localhost access logs (/var/log/tomcat2/localhost_access_log*): These logs should be analyzed because they record internal routing to the Tomcat servlet handling MICS messages, which confirms whether the unauthenticated request reached the JVM container.
  • System process list (ps aux) and audit logs: Active processes must be audited because post-exploitation commands executed by executeNativeCommand run under root or the tomcat user, revealing shell execution or reverse shell commands.
  • Sentry administrator logs: Administrative account modifications must be reviewed because the RCE is often chained with CVE-2026-10523 account creation attempts, helping to identify backdoor administrator accounts.

Timeline

What Happened

Ivanti Sentry gateways expose a configuration servlet endpoint /mics/api/v2/sentry/mics-config/handleMessage that parses XML-formatted command strings. An unauthenticated attacker can POST a payload containing the execute action combined with the /configuration/system/commandexec XPath to Sentry's Tomcat container. Sentry's backend java handler tokenizes the input and passes the malicious XML string directly to executeNativeCommand(), executing the command payload on the host OS as root [labs.watchtowr.com opens in a new tab].

Credential or Data Collection

Sentry appliances store sensitive enterprise credentials, including portal database credentials, ActiveSync tokens, and SSL certificates [ivanti.com opens in a new tab]. An attacker with root execution privileges can extract these secrets directly from the local configuration database and configuration files [ivanti.com opens in a new tab].

Defense Evasion

Exploiting this vulnerability does not trigger authentication alerts because the target API does not enforce session validation [labs.watchtowr.com opens in a new tab]. Attackers can evade basic string WAF rules by using shell parameter expansion like ${IFS} to substitute spaces in commands, bypassing simple tokenization rules [labs.watchtowr.com opens in a new tab].

Exfiltration and Command and Control

Threat actors establish persistent command and control by downloading shell scripts or installing JSP web shells in Sentry's Tomcat webapps/mics directories [labs.watchtowr.com opens in a new tab]. This enables direct, out-of-band communication with attacker infrastructure using standard protocols [labs.watchtowr.com opens in a new tab].

Affected Assets and Blast Radius

Ivanti Sentry appliances deployed at the network edge are the primary targets, exposing internal enterprise directories and mail servers to compromise.

Analysis table
Affected AssetImpactAccess LevelDownstream Risk
Ivanti Sentry ApplianceHost compromiserootLoss of ActiveSync tokens and LDAP credentials
Port 8443 interfacePre-authentication RCEExternalFull network entry
ActiveSync traffic proxyMobile mail interceptProxyEavesdropping on enterprise mail sync

Indicators of Compromise

The following indicators of compromise (IOCs) can be used to scope exposure across local repositories, systems, and telemetry exports:

Downstream Abuse Audits

Compromised workstations expose active API credentials, requiring immediate rotated revocation. The following platforms are at risk:

  • GitHub OIDC and PATs: Attackers harvested SSH private keys and Git Personal Access Tokens. Auditors must inspect recent action runs and release logs during the exposure window.
  • Cloud IAM Credentials: AWS, Azure, and GCP session tokens. CloudTrail and Activity Logs should be queried for AssumeRole or write operations originating from unexpected IP addresses.
  • NPM and Package Registries: Publishing tokens and credentials. Registry profiles must be audited for unauthorized version publishes or token additions.

Remediation and Closure

  1. Preserve evidence: Clone the virtual appliance disk or take VM snapshots before modifying any Sentry configurations, and export /var/log/httpd/ and /var/log/tomcat2/ logs to a secure, centralized server.
  2. Block external access: Restrict access to port 8443 on the Sentry appliance via firewall policies, allowing traffic only from trusted administrative IP blocks.
  3. Update Sentry firmware: Apply the Ivanti patches by updating the appliance firmware to R10.5.2, R10.6.2, or R10.7.1 to address the unauthenticated RCE pathway.
  4. Eradicate persistence: Scan Tomcat webapps/mics and other application directories for newly created .jsp web shells or unexpected scripts, and remove unauthorized accounts.
  5. Rotate credentials: Change the passwords for any LDAP, Active Directory service accounts, database accounts, and TLS certificate private keys configured on the compromised Sentry appliance.
  6. Verify and close: Confirm that the /mics-config/handleMessage endpoint returns a 403 Forbidden or 404 response to unauthenticated external requests, and verify that log scanning shows no new POST traffic.

Sources

  1. Ivanti Sentry Security Advisory (CVE-2026-10520): Vendor advisory detailing vulnerability scope, affected versions, and patch releases. Supported claims: affected versions (prior to R10.5.2, R10.6.2, R10.7.1) and remediation advice. Limitations: does not provide technical RCE exploitation details.
  2. watchTowr Labs Sentry RCE Analysis: Deep technical analysis of the pre-auth OS command injection vulnerability in Sentry. Supported claims: endpoint path /mics/api/v2/sentry/mics-config/handleMessage, StringTokenizer parsing logic, Java reflection via ReflectionUtilities, XML payload keywords (commandexec, reqandres), and patch diff details. Limitations: focuses on lab reconstruction rather than active in-the-wild threat actor telemetry.
  3. CISA Known Exploited Vulnerabilities Catalog (June 11, 2026): Government advisory cataloging active exploitation. Supported claims: KEV addition date (June 11, 2026) and active exploitation status. Limitations: no technical analysis of code defects.
  4. NIST NVD CVE-2026-10520 Database Entry: Government vulnerability database entry. Supported claims: CVSS score (10.0), CWE-78 categorization, and affected CPE configurations. Limitations: secondary data compiler.
  5. Suricata Signature ID 2069909: Emerging Threats signature specification. Supported claims: signature patterns matching handleMessage and commandexec traffic. Limitations: detection signature only, no vulnerability details.

Timeline

3 of 3 rows

Timeline
DateEventDescriptionSource
Jun 11, 2026First seenFirst seen recorded for Ivanti Sentry CVE-2026-10520: KEV Pre-Auth OS Command Injection.Halting Problems dataset
Jun 11, 2026DiscoveryDiscovery recorded for Ivanti Sentry CVE-2026-10520: KEV Pre-Auth OS Command Injection.Halting Problems dataset
Jun 11, 2026DisclosureDisclosure recorded for Ivanti Sentry CVE-2026-10520: KEV Pre-Auth OS Command Injection.Halting Problems dataset

Affected Software

0 of 0 rows

Affected Software
PackageEcosystemVersion RangeStatusConfidenceSource
No rows match the active filters.

Tested Hunting Scripts

1 of 1 rows

Tested Hunting Scripts
TitleLanguageDescriptionRepositorySource
local repository and exported telemetry scopePythonDoes the telemetry scope contain patterns associated with Ivanti Sentry CVE-2026-10520: KEV Pre-Auth OS Command Injection?scripts/local_repository_and_exported_telemetry_scope.py opens in a new tabHalting Problems dataset

Hunt Manifest: local repository and exported telemetry scope

Title
local repository and exported telemetry scope
Question
Does the telemetry scope contain patterns associated with Ivanti Sentry CVE-2026-10520: KEV Pre-Auth OS Command Injection?
Telemetry Family
Python
Repository
scripts/local_repository_and_exported_telemetry_scope.py
Show tested hunting scriptscripts/local_repository_and_exported_telemetry_scope.py
scripts/local_repository_and_exported_telemetry_scope.py opens in a new tabPython
#!/usr/bin/env python3
"""
Scan Ivanti Sentry Apache and Tomcat logs for CVE-2026-10520 exploitation attempts.
Matches POST requests to the unauthenticated handleMessage endpoint or occurrences
of commandexec/reqandres payload keywords in web/application server log directories.

Exit Codes:
  0: Clean (no indicators found)
  1: Compromise (exploitation indicators found)
  2: Execution error
"""

import os
import sys
import argparse
from pathlib import Path

# Known indicators associated with CVE-2026-10520
TARGET_ENDPOINTS = [
    "/mics/api/v2/sentry/mics-config/handleMessage",
    "/api/v2/sentry/mics-config/handleMessage"
]
PAYLOAD_KEYWORDS = [
    "commandexec",
    "reqandres",
    "/configuration/system/commandexec"
]

def scan_file(file_path: Path) -> list:
    """Scan a single log file for indicators."""
    matches = []
    try:
        with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
            for line_no, line in enumerate(f, 1):
                # Check for POST requests targeting the handleMessage endpoint
                for endpoint in TARGET_ENDPOINTS:
                    if "POST" in line and endpoint in line:
                        matches.append({
                            "type": "endpoint_access",
                            "file": str(file_path),
                            "line_number": line_no,
                            "content": line.strip(),
                            "matched": endpoint
                        })
                
                # Check for XML payload keywords (if full requests/payloads are logged)
                for keyword in PAYLOAD_KEYWORDS:
                    if keyword in line:
                        # Exclude self-references or typical log headers if any
                        matches.append({
                            "type": "payload_keyword",
                            "file": str(file_path),
                            "line_number": line_no,
                            "content": line.strip(),
                            "matched": keyword
                        })
    except Exception as e:
        print(f"[-] Warning: Failed to read {file_path}: {e}", file=sys.stderr)
        return []
    return matches

def main():
    parser = argparse.ArgumentParser(
        description="Scan logs for Ivanti Sentry CVE-2026-10520 RCE exploitation indicators."
    )
    parser.add_argument(
        "--log-dir",
        type=str,
        default="/var/log",
        help="Path to the directory containing Sentry logs (e.g. /var/log/httpd or /var/log/tomcat2)"
    )
    args = parser.parse_args()

    log_path = Path(args.log_dir)
    if not log_path.exists():
        print(f"[-] Error: Log directory '{log_path}' does not exist.", file=sys.stderr)
        return 2
    if not log_path.is_dir():
        print(f"[-] Error: Log path '{log_path}' is not a directory.", file=sys.stderr)
        return 2

    print(f"[+] Starting log scan in: {log_path.resolve()}")
    all_matches = []
    
    # We walk the directory to scan files.
    # Exclude binary or compressed logs (.gz, .zip, etc.) to keep scanning simple and safe.
    for root, _, files in os.walk(log_path):
        for file in files:
            file_path = Path(root) / file
            
            # Skip compressed log files
            if file_path.suffix in [".gz", ".zip", ".tar", ".tgz"]:
                continue
                
            # Scan matching log filename patterns or scan all text logs
            if any(pat in file for pat in ["access_log", "localhost_access", "catalina", "httpd", "portal", "message"]):
                print(f"[+] Scanning: {file_path}")
                matches = scan_file(file_path)
                if matches:
                    all_matches.extend(matches)

    if all_matches:
        print("\n[!] SUSPICIOUS LOG ENTRIES DETECTED:")
        for match in all_matches:
            print(f"  [{match['type'].upper()}] File: {match['file']}:{match['line_number']}")
            print(f"    Match: {match['matched']}")
            print(f"    Line:  {match['content']}")
        return 1

    print("[+] Scan completed. No indicators of CVE-2026-10520 found.")
    return 0

if __name__ == "__main__":
    try:
        sys.exit(main())
    except Exception as e:
        print(f"[-] Execution failure: {e}", file=sys.stderr)
        sys.exit(2)

Provenance & Sources

0 of 0 rows

Provenance & Sources
SourceTypeReliabilityClaimsEvidence
No rows match the active filters.