CVE-2023-23902
A buffer overflow vulnerability exists in the uhttpd login functionality of Milesight UR32L v32.3.0.5. A specially crafted network request can lead to remote code execution. An attacker can send a network request to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Milesight UR32L v32.3.0.5
UR32L - https://www.milesight-iot.com/cellular/router/ur32l/
9.8 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-121 - Stack-based Buffer Overflow
The Milesight UR32L is an industrial cellular router. The router features include support for multiple VPNs, a router console shell, firewall and many others.
The router provides an administrative web page to manage its various settings. This web page requires the client to login. The password is AES encrypted and then Base64 encoded before being sent to the server. The uhttpd
’s decrypt_string
function is the one responsible for decrypting the received AES-encrypted, Base64-encoded password in the login process. Following the decrypt_string
function:
void decrypt_string(char *b64_encrypted_password,char *decrypted_password,size_t size_decrypted_password)
{
[...]
uchar stack_decrypted_string [72];
[... init the AES_key variable]
[... init the AES_IV variable]
[... calculate the __size variable value ...]
base64_decoded_string_start = (uchar *)malloc(__size);
[...]
memset(base64_decoded_string_start,0,__size);
processed_len = 0;
base64_decode_string_cursor = base64_decoded_string_start;
do {
// this check allow to base64 decode the string before decrypting it
if ((password_len_ - padding) <= processed_len) {
*base64_decode_string_cursor = '\0';
ctx = EVP_CIPHER_CTX_new();
[... check error ...]
cipher_type = EVP_aes_128_cbc();
processed_len = EVP_DecryptInit_ex(ctx,cipher_type,(ENGINE *)0x0,AES_key,AES_IV);
[... check error ...]
processed_len =
EVP_DecryptUpdate(ctx,stack_decrypted_string,&output_len,base64_decoded_string_start,
(int)(base64_decode_string_cursor +
(-1 - (int)base64_decoded_string_start))); [1]
[... check error ...]
processed_len = output_len;
iVar3 = EVP_DecryptFinal_ex(ctx,stack_decrypted_string + output_len,&output_len);
[... check error ...]
processed_len = processed_len + output_len;
EVP_CIPHER_CTX_free(ctx);
stack_decrypted_string[processed_len] = '\0';
EVP_cleanup();
ERR_free_strings();
free(base64_decoded_string_start);
strncpy(decrypted_password,(char *)stack_decrypted_string,size_decrypted_password); [2]
return;
}
[...]
[... base64 decode ...] [3]
} while( true );
}
This function has three parameters: the b64_encrypted_password
parameter is the AES-encrypted and Base64-encoded password string that will be Base64 decoded and then AES decrypted; decrypted_password
is the destination buffer where the decoded and decrypted password will be copied; size_decrypted_password
is the size of the decrypted_password
buffer.
At [3]
the b64_encrypted_password
string is Base64 decoded and then, at [1]
, the decoded value is AES decrypted into stack_decrypted_string
, a 72-byte long stack buffer. Eventually, at [2]
, size_decrypted_password
bytes will be copied from the stack_decrypted_string
buffer into the decrypted_password
buffer.
In the decrypted_password
only size_decrypted_password
bytes will be copied, which will prevent any type of buffer overflow in the decrypted_password
buffer.
At [1]
the OpenSSL
’s EVP_DecryptUpdate
function will perform the decryption of the Base64 decoded user-controlled data into the stack_decrypted_string
stack buffer. Because the stack_decrypted_string
stack buffer is fixed in size and the decrypted string, provided by a user, can be greater in length than the stack buffer, this can lead to a buffer overflow in the stack_decrypted_string
buffer.
Since the maintainer of this software did not release a patch during the 90 day window specified in our policy, we have now decided to release the information regarding this vulnerability, to make users of the software aware of this problem. See Cisco’s Coordinated Vulnerability Disclosure Policy for more information: https://tools.cisco.com/security/center/resources/vendor_vulnerability_policy.html
2023-02-14 - Initial Vendor Contact
2023-02-21 - Vendor Disclosure
2023-07-06 - Public Release
Discovered by Francesco Benvenuto of Cisco Talos.