The Binarly REsearch team has consistently uncovered security vulnerabilities in the Baseboard Management Controller (BMC) firmware -- a critical component of modern data center infrastructure. These vulnerabilities can be exploited remotely by threat actors, posing significant risk to enterprises.
In a previous report, “Old But Gold: The Underestimated Potency of Decades-Old Attacks on BMC Security,” we documented the BMC architecture in detail and showed that it is still possible to find classes of vulnerabilities known from the early 2000s.
Unfortunately, many vendors fail to implement best security practices and are far away from adopting secure-by-design principles in their products. In another investigation, “How an old bug in Lighttpd gained new life in AMI BMC, including Lenovo and Intel products,” we called attention to old problems that have remained unfixed for years, leaving systems exposed to remote exploitation.
Today, we present a deep dive into CVE-2024-36435, a recently disclosed vulnerability in multiple Supermicro enterprise products that was discovered by Alexander Tereshkin from NVIDIA’s Offensive Security Research Team. The vulnerability got our attention for many reasons: firstly, the vendor agreed on the critical impact; and secondly, the nature of the vulnerability where an unauthenticated user can remotely trigger the code flow with a simple post request and cause the arbitrary code execution over classical stack overflow (CWE-121).
The vulnerability exists in the web component of the BMC system and can be exploited if an attacker has access to the BMC Web server (ports 80/443 by default). No additional conditions such as authentication credentials or user interaction are required for successful exploitation.
When a POST request is issued to /cgi/login.cgi
, it is processed by the login.cgi binary
. In its main function, it first tries to get the name ndpwd
parameters provided by the user. Note that the cgiGetPostVariable
function takes the name of the parameter to be extracted as well as another integer value which is supposed to be the maximum allowed length of this parameter:
name = cgiGetPostVariable("name", 64);
pwd = cgiGetPostVariable("pwd", 64);
The cgiGetPostVariable
function is exported from the libipmi.so
library, only checking that the HTTP method of the incoming request is POST
or DELETE
and that its body is not empty. If these conditions are met, the GetValue
function is called with the name
and size
parameters passed from the previous step and value
– which should contain a pointer to the extracted value:
char *cgiGetPostVariable(const char *name, int size) {
char *value = nullptr;
char *request_method = get_cgi_env("REQUEST_METHOD", 6);
if (!request_method) {
return value;
}
if (post_data && (!strncasecmp(request_method, "POST", 4u) || !strncasecmp(request_method, "DELETE", 6u))) {
GetValue(name, &value, size);
} else {
console_log("HTTP get method for %s is not allowed!\n", name);
}
return value;
}
The following screenshot is the beginning of the GetValue
function decompiled with IDA, with only identified 2 parameters – name
and value
:
This is because size
is never used in this function, meaning the resulting value
can point to the string of length much more than it should.
After name
and pwd
are obtained, this code follows:
if (cgiGetPostVariable("check", 5)) {
if (name) {
name_decoded[base64decode(name, name_decoded)] = 0;
name = name_decoded;
}
if (pwd) {
pwd_decoded[base64decode(pwd, pwd_decoded)] = 0;
pwd = pwd_decoded;
}
}
If the request also contains a non-empty check
parameter, this tells the web server that the request parameters should be base64 decoded before processing. And crucially, decoded strings are stored in buffers allocated on the stack, the length of which (256 bytes) is much smaller than the length of possible value written to it:
All of this gives us a primitive to overwrite the stack of the target login.cgi
process running as root on the BMC system. Among other things, this binary wasn't configured to use stack canaries:
With this, and although NX mitigation is enabled, exploitation is trivial using ROP gadgets from libc – in our demo PoC we make multiple attempts to guess the base address of libc, which is not a problem, as from our experiments 100 requests are enough to achieve code execution inside the BMC system:
In a previous investigation, “Repeatable Failures: Test Keys Used to Sign Production Software…Again?”, the Binarly REsearch team uncovered the use of non-production cryptographic keys for validating BMC firmware. An exploit for this flaw could potentially compromise the entire firmware execution root-of-trust chain. When combined with the impact of CVE-2024-36435 and the BRLY-2024-023 vulnerability, this issue could allow an attacker to manipulate the boot process and establish persistence on the BMC device.
First, by exploiting the buffer overflow vulnerability, an attacker can gain unauthorized root access to the BMC operating system that provides privileges to the update delivery process for the BMC and server system firmware. Then, if an attacker obtains a private part of the non-production key used by the vendor to sign the BMC firmware (which can happen, as we documented with PKfail), malicious BMC updates can be delivered to gain persistence.
The updated version of GetValue
includes an additional call to the create_tlv
function, which takes the maximum allowed value size as an input argument. If the allowed size is less than the length of the POST
parameter value after url decoding – then an empty result will be returned:
Interestingly, we saw a similar implementation in firmware images released much earlier (2022) which may indicate that the bug was previously known but the fix wasn't applied to all product lines. This is another case that highlights the difficulty of the supply chain security process.
Unfortunately, BMC vulnerabilities are not rare, and the security state, in many cases, does not even follow basic security principles, as you can see from the discussed vulnerabilities. Last year, NSA released “Harden Baseboard Management Controllers” concerning about blind spots in the firmware space which could be used by threat actors to gain the stealth persistence from traditional endpoint security solutions.
The Binarly Transparency Platform effectively catches malicious implantation and exploitation of vulnerabilities, including the critical CVE-2024-36435 Supermicro flaw.
From the results of scanning our internal firmware dataset, we know that these Supermicro products are potentially affected by this issue:
We encourage all enterprises to check the manufacturer's advisory page for information on patches.