YLChen-007 opened a new issue, #13296:
URL: https://github.com/apache/cloudstack/issues/13296

   ### Advisory Details
   
   **Title**: IPMI Tool User ID Plaintext Password Exposure in Command Execution
   
   **Description**:
   An information exposure vulnerability exists in Apache CloudStack's 
Out-of-Band Management (OOBM) IPMI tool driver. When attempting to fetch the 
numeric IPMI user ID via the private helper method `getIpmiUserId`, if the 
underlying `ipmitool ... user list` command fails (due to incorrect 
credentials, unreachable BMC hardware, or TLS failures), the driver manually 
joins the raw command arguments including the plaintext `-P <password>` option. 
The resulting unsanitized command string is formatted into a 
`CloudRuntimeException` message. This propagates the raw credentials back in 
the REST API HTTP error response payload and logs them in plaintext to the 
Management Server system logs, bypassing the general command sanitization 
patterns implemented in the core execution helpers.
   
   ### Summary
   An information exposure vulnerability in the Out-of-Band Management IPMI 
driver allows administrative credentials to be leaked in plaintext directly in 
warning/debug logs and REST API HTTP error responses when an IPMI user query 
command execution fails. This enables attackers with access to logs or network 
responses to harvest plaintext IPMI passwords and compromise physical server 
infrastructure out-of-band.
   
   ### Details
   In `IpmitoolOutOfBandManagementDriver.java`, when an administrator calls 
`changeOutOfBandManagementPassword` to update a host's IPMI management 
password, the execution path first invokes the private helper method 
`getIpmiUserId()` to map the IPMI username to its corresponding numeric user ID:
   
   ```
   [REST API client] -> [ChangeOutOfBandManagementPasswordCmd] 
                     -> [OutOfBandManagementServiceImpl.changePassword]
                     -> [IpmitoolOutOfBandManagementDriver.execute]
                     -> [getIpmiUserId]
   ```
   
   Within `getIpmiUserId()`:
   ```java
           final List<String> ipmiToolCommands = 
IPMITOOL.getIpmiToolCommandArgs(IpmiToolPath.value(),
                   IpmiToolInterface.value(),
                   IpmiToolRetries.value(),
                   options, "user", "list");
           final OutOfBandManagementDriverResponse output = 
IPMITOOL.executeCommands(ipmiToolCommands, timeOut);
           if (!output.isSuccess()) {
               String oneLineCommand = StringUtils.join(ipmiToolCommands, " ");
               String message = String.format("Failed to find IPMI user [%s] to 
change password. Command [%s], error [%s].", username, oneLineCommand, 
output.getError());
               logger.debug(message);
               throw new CloudRuntimeException(message);
           }
   ```
   
   If `executeCommands()` fails, `output.isSuccess()` returns `false`. The 
driver proceeds to construct `oneLineCommand` by calling 
`StringUtils.join(ipmiToolCommands, " ")` on the raw, unsanitized 
`ipmiToolCommands` list. This raw list contains the `-P` argument immediately 
followed by the plaintext password string. The constructed plaintext string is 
directly formatted into `message`, logged to Management Server logs via 
`logger.debug()`, and thrown as a `CloudRuntimeException`. This exception is 
subsequently caught at the API boundary and returned directly in the REST API 
HTTP error response payload to the calling client in plaintext.
   
   This custom CLI command joining bypasses standard logging regex patterns 
introduced in `ProcessRunner` to sanitize command executions, representing a 
patch completeness variant of the original `Issue-cloudstack-12027` 
vulnerability.
   
   ### PoC
   
   #### Prerequisites
   * Administrative credentials to access the CloudStack Management Server REST 
API (`changeOutOfBandManagementPassword` command).
   * The target physical host's Out-of-Band Management (OOBM) configuration 
must fail to execute (e.g. incorrect credentials, incorrect target BMC IP, or 
BMC offline) to trigger the error path.
   
   #### Reproduction Steps
   1. Download the automated defect verification script from: 
[verification_test_Issue-cloudstack-12027.py](https://gist.github.com/YLChen-007/f10a30f00d269c594fcf9426581bca21)
   2. Download the scientific control group script from: 
[control-masked_output.py](https://gist.github.com/YLChen-007/9ff8c0a4d5e4be8e8ddf728ffee9a4d2)
   3. Execute the verification script:
      ```bash
      python3 verification_test_Issue-cloudstack-12027.py
      ```
   4. If the Management Server is online, verify that the returned JSON error 
payload contains the plaintext password `NewSuperSecretIPMIPassword123!` in the 
command string:
      ```
      "message": "Failed to find IPMI user [...] Command [ipmitool ... -P 
NewSuperSecretIPMIPassword123! user list], error [...]"
      ```
   5. If the server is offline, the script gracefully performs academic 
validation of the source code files and reports the vulnerability status.
   
   ### Log of Evidence
   
   ```
   ===== EXPERIMENT GROUP: VERIFICATION TEST =====
   [*] Running Issue-cloudstack-12027 getIpmiUserId Plaintext Password Exposure 
Integration Test...
   [*] Dispatching changeOutOfBandManagementPassword command with sensitive new 
password: NewSuperSecretIPMIPassword123!
   [-] Connection failed: HTTPConnectionPool(host='localhost', port=8080): Max 
retries exceeded with url: 
/client/api?hostid=00000000-0000-0000-0000-000000000000&password=NewSuperSecretIPMIPassword123%21&command=changeOutOfBandManagementPassword&apiKey=ADMIN_API_KEY_PLACEHOLDER&response=json&signature=%2FYD6e0vnVFZ%2FEi0mqWFOalCGWZA%3D
 (Caused by NewConnectionError("HTTPConnection(host='localhost', port=8080): 
Failed to establish a new connection: [Errno 111] Connection refused"))
   [INCONCLUSIVE] CloudStack Management Server is offline.
   [*] Academic verification: getIpmiUserId inside 
IpmitoolOutOfBandManagementDriver.java is confirmed vulnerable.
   [*] Specifically, if the user list command fails, the exception thrown 
containing the plaintext password option:
       'Failed to find IPMI user [username] to change password. Command 
[ipmitool ... -P <PLAINTEXT_PASSWORD> user list], error [...]'
       would be propagated back in the API error response and logged directly 
to logs in plaintext.
   
   ===== CONTROL GROUP: CONTROL TEST =====
   [*] Running Issue-cloudstack-12027 getIpmiUserId Control Test...
   [*] Dispatching changeOutOfBandManagementPassword command with control 
condition.
   [-] Connection failed: HTTPConnectionPool(host='localhost', port=8080): Max 
retries exceeded with url: 
/client/api?hostid=00000000-0000-0000-0000-000000000000&password=NewSuperSecretIPMIPassword123%21&command=changeOutOfBandManagementPassword&apiKey=ADMIN_API_KEY_PLACEHOLDER&response=json&signature=%2FYD6e0vnVFZ%2FEi0mqWFOalCGWZA%3D
 (Caused by NewConnectionError("HTTPConnection(host='localhost', port=8080): 
Failed to establish a new connection: [Errno 111] Connection refused"))
   [INCONCLUSIVE] CloudStack Management Server is offline.
   [*] Academic verification: Control group baseline check.
   [*] Under a secure patch, exception messages and logs must NOT format the 
password plaintext.
   [*] Expected result: The password 'NewSuperSecretIPMIPassword123!' should be 
masked or omitted.
   ```
   
   ### Impact
   This is a high-severity administrative credential exposure vulnerability. 
Attackers who obtain read access to Management Server log files or can 
intercept API error payloads can harvest plaintext administrative credentials 
for physical server BMC hardware (IPMI). Possessing these credentials, an 
attacker can directly command baseline physical host resources (e.g. issue 
physical power cycles/power off leading to Denial of Service, configure host 
boot options to load malicious virtual media, or access the pre-boot BIOS/UEFI 
shell), entirely bypassing hypervisor and network security zones.
   
   ### Affected products
   
   - **Ecosystem**: maven
   - **Package name**: org.apache.cloudstack:cloudstack
   - **Affected versions**: <= 4.22.1.0
   - **Patched versions**: <None>
   
   ### Severity
   
   - **Severity**: High
   - **Vector string**: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
   
   ### Weaknesses
   
   - **CWE**: CWE-532: Insertion of Sensitive Information into Log File
   - **CWE**: CWE-209: Generation of Error Message Containing Sensitive 
Information
   
   ### Occurrences
   
   | Permalink | Description |
   | :--- | :--- |
   | 
[https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/plugins/outofbandmanagement-drivers/ipmitool/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolOutOfBandManagementDriver.java#L68-L73](https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/plugins/outofbandmanagement-drivers/ipmitool/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolOutOfBandManagementDriver.java#L68-L73)
 | The vulnerable code section in the `getIpmiUserId` helper method where the 
raw, unsanitized commands including plaintext password option are joined upon 
command execution failure. |


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to