MOKSHA-2026-0001: Arbitrary Host Device Mount via VBD.other_config backend-local

Advisory IDMOKSHA-2026-0001
Semantic IDBOC-1
Published2026-04-24
CVSS 3.19.9 Critical
CVSS 3.1 VectorAV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CVSS 4.09.4 Critical
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
XAPI ObjectVBD
XAPI Fieldother_config:backend-local
Entry Rolevm-admin
ResearcherJakob Wolffhechel, Moksha

Affected Products

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

Summary

A user with the vm-admin role - the lowest delegated management role in XAPI-based hypervisors (XenServer, XCP-ng) - can mount any host block device as a guest virtual disk by writing an arbitrary filesystem path to VBD.other_config:backend-local. The attack requires a single API call, no exploit code, no shell access, and produces no security alerts. The vulnerability collapses the entire XAPI RBAC hierarchy: a vm-admin gains root-equivalent access to the hypervisor host, can read any co-hosted VM's disk, exfiltrate credentials, inject SSH backdoors, and move laterally across shared storage - all from a single delegated admin credential.

Vulnerability Description

VBD.other_config is a Map(String, String) field in the XAPI data model. The backend-local key overrides the normal storage path for a virtual block device. When a VBD is plugged (via VM start or hotplug), XAPI reads this key in xapi_xenops.ml:backend_of_vbd and passes the path directly to xenopsd with no validation, no access control check, and only a warn-level log message.

The code path:

  1. vm-admin calls VBD.add_to_other_config(vbd, "backend-local", "/dev/sda1")
  2. On VBD plug, xapi_xenops.ml:backend_of_vbd reads other_config["backend-local"]
  3. The path is forwarded to xenopsd as the VBD backend device
  4. xenopsd writes the path to xenstore; blkback opens it in dom0
  5. The guest VM sees the host block device as a virtual disk

No validation occurs at any stage. The warn-level log message ("Using local override for VBD backend") is the only trace of the operation.

Root Causes

  1. Missing RBAC protection. VBD.other_config has zero map_keys_roles entries in datamodel.ml. Every infrastructure-critical key, including backend-local, is writable by vm-admin via add_to_other_config.

  2. Missing consumer-side validation. backend_of_vbd in xapi_xenops.ml consumes the backend-local key without any path validation, access control check, or security-level logging.

  3. set_other_config RBAC bypass. The set_other_config method replaces the entire map atomically and bypasses map_keys_roles per-key checks entirely. This is a pre-existing architectural limitation shared by all XAPI objects.

  4. Insufficient logging. The only indicator is a warn-level message. No security alert, no RBAC denial event, no anomaly detection trigger.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Confirmed (Live-Tested)

Scenario Impact Status
S1: Cross-VM VDI exfiltration Read any co-hosted VM's disk contents Confirmed
S2: Host root filesystem read Read /etc/shadow, XAPI state.db, SSH keys 8/8 PASS
S3: RBAC hierarchy collapse Self-grant pool-admin via on-disk database edit 7/7 PASS (dom0), guest-side PoC ready
S4: SSH key injection backdoor Persistent root SSH access surviving reboots 8/8 PASS
S5: Shared storage lateral movement Read VDIs across hosts via shared NFS/iSCSI 9/9 PASS

Additional Scenarios

Scenario Impact Status
S6: BOC-1 + SMC-1 chain Silent storage protocol injection against storage arrays Code-traced
S7: Cross-host local SR exfiltration Read VDIs from remote host's local storage PoC ready
S8: USB device exfiltration Mount host USB storage as guest disk PoC ready

Escalation Chain

vm-admin credential (single API call)
    |
    v
S1: Read any VM's VDI on the same host
    |
    +---> S7: Read VDIs from remote host's local storage
    |
    v
S2: Read the host root filesystem
    |
    +---> S3: Self-grant pool-admin (permanent RBAC collapse)
    +---> S4: SSH key injection (persistent root access)
    +---> S5: Shared storage lateral movement (pool-wide compromise)
    +---> S6: pool-admin + SMC-1 (silent storage array attacks)
    +---> S8: USB device exfiltration

Detection

There is no reliable post-compromise detection. The S3 RBAC collapse leaves no API audit trail because the role change is loaded from the tampered on-disk database at XAPI startup, not modified through the API. XAPI performs no integrity verification on state.db at load time.

Remediation

Short-Term Mitigations

Long-Term Fix

Layer 1 - RBAC (Patch 0001): Add map_keys_roles entries to VBD.other_config in datamodel.ml. The backend-local key requires _R_LOCAL_ROOT_ONLY (no API user can set it). The backend-kind key requires _R_POOL_ADMIN.

Layer 2 - Validation (Patch 0002): Add a config-driven validation gate in xapi_xenops.ml:backend_of_vbd. A new flag allow_vbd_backend_local (default: false) rejects the override when disabled. Defense-in-depth: blocks the attack even if RBAC is bypassed via set_other_config.

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