The office mail-sorting robot accepts a note that says "deliver a bomb" and dutifully obeys
Control-M/Server is BMC's enterprise workload-automation brain — the scheduler that dispatches batch jobs, file transfers, ETL pipelines, and database maintenance to Control-M/Agent processes running across thousands of managed hosts. A communication command in the server-side listener fails to sanitize attacker-supplied input, letting an unauthenticated network attacker inject unauthorized commands that execute in the context of the Control-M/Server process itself. Per BMC, affected builds are 9.0.20.x through 9.0.21.200 inclusive, plus older unsupported branches; the fix is expected in the next 9.0.21 rollup.
Vendor severity of CRITICAL / 9.0 is fair — arguably conservative. CVSS AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H captures the ingredients, but the AC:H (some race/config precondition) is the only thing that shaved this off a 9.8. Reality is that Control-M/Server is the *definition* of a high-value-role component: successful RCE on the server yields arbitrary command execution on every agent-managed host it schedules against, plus the service accounts, DB creds, and file-transfer material stored on the scheduler. This is a fleet-pivot bug, not a single-host bug.
5 steps from start to impact.
Reach the Control-M/Server communication port
7005 for the server-agent CTM protocol, plus configuration/utility ports). This is normally an internal-only service, so the attacker is typically an already-inside actor: pentester, insider, malware on a jump host, or a compromised Control-M/Agent host pivoting back up-stream. Reconnaissance tools: nmap -sV -p 7005-7030, masscan, or a Control-M/EM console fingerprint.- Network path to Control-M/Server management VLAN
- Server exposes the CTM communication port (default listener enabled)
- Control-M/Server is almost never internet-exposed — GreyNoise/Shodan population is effectively noise-floor
- Mature shops segment the batch-automation VLAN from user desktops
7005/tcp from non-agent sources; EDR on the jump host that originated the probeCraft the injection payload against the vulnerable command
AC:H in the vector implies a non-trivial precondition — likely a specific message ordering, a length or encoding trick, or a race with a legitimate agent connection. Expect a PoC from watchTowr, Assetnote, or SSD Secure Disclosure within 2-6 weeks once a patch diff is available.- Understanding of the CTM message framing
- Ability to satisfy the AC:H precondition (timing/state)
- Proprietary binary protocol raises the reverse-engineering cost
- No public PoC at time of disclosure
Achieve RCE as the Control-M service account
controlm domain service account or LocalSystem; on Linux it's the controlm UNIX user with sudo entries to run job-plan scripts. Either way the attacker now controls the scheduler brain. Post-exploit tools: Impacket, Cobalt Strike, Sliver, or a simple in-memory Cs2Bus/reverse shell.- Vulnerable Control-M/Server 9.0.20.x – 9.0.21.200
- Some hardened deployments run Control-M/Server as a non-privileged local account with restricted sudo — limits initial blast on the box itself
- EDR on the scheduler host may catch classic post-ex tooling
controlm service spawning cmd.exe, powershell.exe, /bin/sh, or curl; sudden outbound C2Weaponize the scheduler to push jobs to every agent
Control-M/Agent on managed hosts using an authenticated channel established at agent-registration time — the server is trusted by every agent. An attacker with RCE on the server can insert or modify job definitions to run arbitrary commands on any agent-managed host: Run-As fields, pre/post scripts, or SMART Folder job actions. Tooling: native ctmcreate, ctmpsm, or direct DB writes to the Control-M schema.- Persistent agent trust relationships (the default)
- Access to the Control-M DB or
ctm*CLIs on the compromised server
- Some shops require change-management approval for new job definitions — but attacker owns the approver's authoring path
- Agent-side allow-listing of run-as accounts is rare in practice
Run-As accounts, spikes in ad-hoc job creation outside change windows; SIEM correlation against ITSM/change ticketsLoot creds, pivot to identity plane, ransomware or data theft
Mimikatz, Rubeus, SharpChromium on scheduler-adjacent admin hosts, rclone for egress.- Steps 1-4 completed
- Agents deployed on regulated / high-value targets
- Vaulted creds (CyberArk / HashiCorp Vault integration) reduce plaintext exposure — but agents still execute jobs on request
- Well-instrumented EDR catches Mimikatz on the scheduler host
The supporting signals.
| In-the-wild exploitation | None observed as of 2026-07-01. No GreyNoise tag, no CISA KEV listing, no public IR reports. |
|---|---|
| Public PoC | No public PoC at disclosure. Expect diffing within 2-6 weeks; watch watchTowr Labs, Assetnote, and SSD Secure Disclosure for follow-ups on BMC advisories. |
| EPSS | Not yet scored (disclosure day); expected initial band 0.1–1% rising after PoC drops. |
| CISA KEV | Not listed. No federal due-date. |
| CVSS 3.1 | AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H → 9.0 CRITICAL. AC:H reflects a non-trivial precondition; scope change reflects impact beyond the vulnerable component (agents). |
| Affected versions | Control-M/Server 9.0.20.x through 9.0.21.200 (inclusive) plus older unsupported branches (e.g., 9.0.19.x). |
| Fixed versions | 9.0.21.201 rollup / equivalent hotfix per BMC advisory. SaaS-managed Control-M tenants receive vendor-side patching. |
| Attack surface exposure | Control-M/Server is an *internal-only* orchestration component. Shodan/Censys show <100 exposed listeners globally — the realistic exposure is post-initial-access lateral, not internet-scan. |
| Disclosure | 2026-07-01 by BMC Software via customer support portal + docs.bmc.com announcement. |
| Reporting researcher | Coordinated disclosure via BMC PSIRT; original reporter not yet publicly credited. |
noisgate verdict.
The single decisive factor is role multiplier — Control-M/Server is a canonical fleet-orchestration high-value component, and a compromised scheduler ends in arbitrary command execution on every Control-M/Agent-managed host in the enterprise. Internal-only exposure narrows the attacker population but cannot break the CRITICAL floor for a component whose entire purpose is to run commands fleet-wide.
Why this verdict
- Role multiplier (decisive): Control-M/Server occupies the fleet-orchestration high-value role by *definition* — ~100% of installs sit in this role. RCE on the scheduler yields command execution on every agent host it manages, plus the credential/vault material used to run jobs. This is the same class of blast radius as compromising a Jenkins controller, an SCCM primary, or a Rundeck server. That alone floors the verdict at CRITICAL.
- Unauthenticated, network-reachable, no user interaction:
AV:N/PR:N/UI:N. Any attacker with L3 reachability to the CTM listener can attempt exploitation. - Friction adjustment (does NOT break the floor): The scheduler is internal-only in ~99% of deployments, so the attacker must already have a foothold on the corporate network — this narrows attacker population but does not reduce blast radius. Per the noisgate role-multiplier rule this can pull the verdict ABOVE the floor but not BELOW it; here it holds at CRITICAL rather than pushing beyond.
- AC:H precondition: Non-trivial timing/state requirement will slow public PoC development by 2-6 weeks. This trims the score from 9.8 → 9.2 but does not change the bucket.
- No KEV / no PoC yet: Justifies not weighting this as an active-exploitation emergency, but for a scheduler that owns the batch plane of a Fortune-500, the pre-PoC window IS the patch window.
Why not higher?
No public PoC, no active exploitation, and AC:H reflects a real precondition attackers must satisfy. The listener is not internet-exposed in any meaningful population, so the immediate 'ransomware group scanning tomorrow' scenario doesn't fit — that's what separates a 9.2 from a 9.8 emergency like a public-facing edge-appliance RCE.
Why not lower?
Downgrading past CRITICAL would require evidence that Control-M/Server is NOT a fleet-orchestration component — it is, by design. Every credible deployment ends the chain at fleet command execution and credential loot. 'Requires internal access' is not sufficient friction to break the floor for a scheduler; the role multiplier rule explicitly overrides friction-only downgrades here.
What to do — in priority order.
- ACL the CTM listener to known agent hosts only — On the Control-M/Server host, restrict inbound
7005/tcp(and any configured server ports) to the known agent CIDR list via host firewall (Windows Firewallinbound rules,nftables/iptableson Linux) plus upstream VLAN ACLs. Deploy within 3 days per the noisgate CRITICAL mitigation SLA. This blocks the pre-auth reachability step for any attacker who isn't already on an agent-registered host. - Deploy vendor hotfix / rollup 9.0.21.201 — Apply BMC's fix build across every Control-M/Server node — active-active pairs, DR replicas, and staging must all be patched together to prevent asymmetric exposure. Target completion within 90 days per the noisgate CRITICAL remediation SLA; realistically most shops can do this inside 2 weeks given Control-M's patch tooling.
- Rotate Control-M service-account and vaulted-job credentials — Assume any credential referenced by a job definition or stored in the Control-M vault is compromised until proven otherwise. Rotate DB, SFTP, cloud-API, and mainframe credentials referenced from job plans; force re-enrollment of agent trust if you have any indication the scheduler was reachable from an untrusted segment.
- Turn on job-plan change auditing and alert on out-of-window creation — Enable Control-M audit logging, forward to SIEM, and alarm on job definitions created or modified outside your change window or by accounts other than approved schedulers. This is the primary detection for step 4 (weaponized job push) if steps 1-3 succeed anyway.
- Segregate the scheduler host from user-desktop VLANs — If Control-M/Server currently sits in a general-server VLAN reachable from the desktop plane, move it into an isolated batch-management VLAN with jump-host-only admin access. This raises the cost of the 'insider or malware-on-workstation' reachability path.
- WAF or reverse proxy in front of Control-M/Server — the CTM protocol is proprietary binary, not HTTP; a web WAF has no signatures for it.
- MFA on Control-M/EM console — the vulnerability is in the server-agent communication path, not in the EM web UI, so console MFA does not close the hole.
- Disabling unused agents — the listener still accepts connections; the vulnerable command is exposed regardless of how many agents are registered.
- EDR on the scheduler host alone — helpful for detecting post-ex, but the initial RCE happens inside the trusted
controlmservice process; EDR is a detective control, not preventive against the injection itself.
Crowdsourced verification payload.
Run this on each Windows Control-M/Server host as a local administrator (Linux operators can adapt using ctm_menu + rpm -q/dpkg -l). Example invocation from an elevated PowerShell prompt: .\Check-CVE-2026-10539.ps1 -CtmHome 'C:\ProgramData\BMC Software\Control-M Server'. Reports VULNERABLE, PATCHED, or UNKNOWN.
#requires -Version 5.1
<#
Check-CVE-2026-10539.ps1
Detects Control-M/Server builds in the vulnerable range 9.0.20.x .. 9.0.21.200.
Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
#>
param(
[string]$CtmHome = $env:CONTROLM_SERVER_HOME
)
function Get-CtmServerVersion {
param([string]$Home)
# 1) Preferred: ctm_menu / ctmgetcm output
$ctmgetcm = Join-Path $Home 'exe\ctmgetcm.exe'
if (Test-Path $ctmgetcm) {
try {
$out = & $ctmgetcm '-version' 2>$null
if ($out -match '(\d+\.\d+\.\d+\.\d+)') { return $Matches[1] }
} catch {}
}
# 2) Fallback: file version on the main server binary
$bin = Join-Path $Home 'exe\ctmsys.exe'
if (Test-Path $bin) {
return (Get-Item $bin).VersionInfo.FileVersion
}
# 3) Registry fallback
$reg = 'HKLM:\SOFTWARE\BMC Software\Control-M/Server'
if (Test-Path $reg) {
$v = (Get-ItemProperty $reg -ErrorAction SilentlyContinue).Version
if ($v) { return $v }
}
return $null
}
function Compare-Version {
param([string]$V)
# Vulnerable: 9.0.20.0 <= V <= 9.0.21.200
$parts = $V.Split('.') | ForEach-Object { [int]$_ }
if ($parts.Count -lt 4) { return 'UNKNOWN' }
$vObj = [Version]::new($parts[0],$parts[1],$parts[2],$parts[3])
$low = [Version]'9.0.20.0'
$high = [Version]'9.0.21.200'
$fixed = [Version]'9.0.21.201'
if ($vObj -ge $fixed) { return 'PATCHED' }
if ($vObj -ge $low -and $vObj -le $high) { return 'VULNERABLE' }
if ($vObj -lt $low) { return 'VULNERABLE' } # unsupported older branches per BMC advisory
return 'UNKNOWN'
}
if (-not $CtmHome -or -not (Test-Path $CtmHome)) {
Write-Output 'UNKNOWN: Control-M/Server home not found. Pass -CtmHome explicitly.'
exit 2
}
$ver = Get-CtmServerVersion -Home $CtmHome
if (-not $ver) {
Write-Output 'UNKNOWN: could not determine Control-M/Server version.'
exit 2
}
$state = Compare-Version -V $ver
Write-Output ("{0}: Control-M/Server version {1}" -f $state, $ver)
switch ($state) {
'PATCHED' { exit 0 }
'VULNERABLE' { exit 1 }
default { exit 2 }
}
If you remember one thing.
9.0.21.201. Anything in the 9.0.20.x – 9.0.21.200 band gets host-firewalled to known-agent CIDRs *today* and patched inside 3 days per the noisgate mitigation SLA, with the vendor rollup deployed fleet-wide inside 90 days per the noisgate remediation SLA (realistically 1-2 weeks given how few scheduler nodes any enterprise runs). Rotate Control-M service-account creds and any credentials stored in job vaults on patched nodes, and turn on job-plan change auditing to SIEM so that if a PoC drops before your patch window closes, you catch the step-4 weaponization instead of finding out from the backup team that jobs ran at 03:00 that nobody scheduled.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.