Talos Vulnerability Report

TALOS-2023-1726

Weston Embedded uC-HTTP HTTP Server buffer overflow vulnerability

November 14, 2023
CVE Number

CVE-2023-25181

SUMMARY

A heap-based buffer overflow vulnerability exists in the HTTP Server functionality of Weston Embedded uC-HTTP v3.01.01. A specially crafted set of network packets can lead to arbitrary code execution. An attacker can send a malicious packet to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Weston Embedded uC-HTTP v3.01.01
Weston Embedded Cesium NET 3.07.01
Silicon Labs Gecko Platform 4.3.1.0

PRODUCT URLS

uC-HTTP - https://weston-embedded.com/micrium/overview Cesium NET - https://www.weston-embedded.com/cesium-cs-net Gecko Platform - https://www.silabs.com/developers/gecko-software-development-kit

CVSSv3 SCORE

9.0 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-122 - Heap-based Buffer Overflow

DETAILS

The uC-HTTP server implementation is designed to be used on embedded systems that are running the µC/OS II or µC/OS III RTOS kernels. This HTTP server supports many features including persistent connections, form processing, chunked transfer encoding, HTTP header fields processing, HTTP query string processing and dynamic content.

This overflow occurs when parsing the Protocol Version of an HTTP request. If the protocol Version string within the HTTP request is prepended with bytes whose value is less than 0x21 (exclamation point in ascii) or greater than 0x7e (tilde in ascii) [1], and the HTTP request does not contain a carriage return character followed by a line feed character [2], it is possible to cause an integer underflow condition within the internal variable used to store the remaining length of the receive buffer [3].

/* HTTPsReq_ProtocolVerParse */
static  void  HTTPsReq_ProtocolVerParse (HTTPs_INSTANCE  *p_instance,
                                     HTTPs_CONN      *p_conn,
                                     HTTPs_ERR       *p_err)
{
...
    len = p_conn->RxBufLenRem;
...
                                                                /* Move the pointer to the next meaningful char.        */
    p_protocol_ver_start = HTTP_StrGraphSrchFirst(p_conn->RxBufPtr, len);       /* [1] p_protocol_ver_start advances to the first character 
                                                                                    between 0x21 - 0x7e */
    if (p_protocol_ver_start == DEF_NULL) {
    *p_err               = HTTPs_ERR_REQ_FORMAT_INVALID;
        return;
    }
                                                                /* Find the end of the request line.                    */
    p_protocol_ver_end = Str_Str_N(p_protocol_ver_start, STR_CR_LF, len);       /* [2] this will search outside of the buffer since len 
                                                                                    does not account for the previously skipped characters in [1] */
    if (p_protocol_ver_end == DEF_NULL) {                       /* If not found, check to get more data.                */
        if (p_conn->RxBufPtr != p_conn->BufPtr) {
        *p_err = HTTPs_ERR_REQ_MORE_DATA_REQUIRED;
        } else {
        *p_err = HTTPs_ERR_REQ_FORMAT_INVALID;
        }
        return;
    }
...
                                                                /* Update the RxBuf ptr.                                */
    p_conn->RxBufLenRem      -= (p_protocol_ver_end - p_conn->RxBufPtr) + 2;    /* [3] Since p_protocol_ver_end can be outside of the 
                                                                                    original buffer, this could lead to an integer underflow */
    p_conn->RxBufPtr          =  p_protocol_ver_end + 2;
...
}

After the integer underflow occurs, the underflowed length value p_conn->RxBufLenRem is used as a length for Mem_Copy [1], which does overflow the original buffer p_conn->BufPtr. Next, the underflowed length value is again used to calculate the pointer that will be used on a subsequent call to receive [2], which results in attacker-controlled data being written outside of the bounds of the receive buffer. It is possible for an attacker to leverage this vulnerability to gain arbitrary code execution.

CPU_BOOLEAN  HTTPsSock_ConnDataRx (HTTPs_INSTANCE  *p_instance,
                               HTTPs_CONN      *p_conn)
{
...
    if ((p_conn->RxBufLenRem > 0) &&
        (p_conn->RxBufPtr   != p_conn->BufPtr)) {               /* If data is still present in the rx buf.              */
                                                                /* Move rem data to the beginning of the rx buf.        */
            Mem_Copy(p_conn->BufPtr, p_conn->RxBufPtr, p_conn->RxBufLenRem);        //[1] the length used here is very large because of the underflow
    }
    p_buf   = p_conn->BufPtr + p_conn->RxBufLenRem;                             //[2] p_buf now points very far outside of the original buffer
    buf_len = p_conn->BufLen - p_conn->RxBufLenRem;
...
    rx_len = (CPU_INT16U)NetSock_RxDataFrom(        p_conn->SockID,
                                            (void *)p_buf,
                                                    buf_len,
                                                    NET_SOCK_FLAG_NO_BLOCK,
                                                &p_conn->ClientAddr,
                                                &addr_len_client,
                                                    DEF_NULL,
                                                    DEF_NULL,
                                                    DEF_NULL,
                                                &err);
...
}

Crash Information

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r
eax            0x41414141          1094795585
ecx            0x0                 0
edx            0x56586ddc          1448635868
ebx            0x56575f64          1448566628
esp            0xffffd45c          0xffffd45c
ebp            0xffffd478          0xffffd478
esi            0xf7f91000          -134672384
edi            0xf7f91000          -134672384
eip            0x41414141          0x41414141
eflags         0x10292             [ AF SF IF RF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
k0             0x0                 0
k1             0x0                 0
k2             0x0                 0
k3             0x0                 0
k4             0x0                 0
k5             0x0                 0
k6             0x0                 0
k7             0x0                 0
(gdb) bt
#0  0x41414141 in ?? ()
#1  0x56557e76 in HTTPs_ConnCloseHook (p_instance=0x5657645c <Mem_Heap+28>, p_conn=0x56576988 <Mem_Heap+1352>, p_hook_cfg=0x0)
    at app_basic_http-s_hooks.c:1299
#2  0x5655cd7e in HTTPsConn_Close (p_instance=0x5657645c <Mem_Heap+28>, p_conn=0x56576988 <Mem_Heap+1352>)
    at Server/Source/http-s_conn.c:334
#3  0x5655caa3 in HTTPsConn_Process (p_instance=0x5657645c <Mem_Heap+28>) at Server/Source/http-s_conn.c:150
#4  0x5655ee9b in HTTPsTask_InstanceTaskHandler (p_instance=0x5657645c <Mem_Heap+28>) at Server/Source/http-s_task.c:814
#5  0x5655ec01 in HTTPsTask_InstanceTask (p_data=0x5657645c <Mem_Heap+28>) at Server/Source/http-s_task.c:653
#6  0x565669ac in KAL_TaskCreate (task_handle=..., p_fnct=0x5655ebdc <HTTPsTask_InstanceTask>, p_task_arg=0x5657645c <Mem_Heap+28>, 
    prio=17 '\021', p_cfg=0x0, p_err=0xffffd5e0) at uc-shims/Source/kal-shim.c:59
#7  0x5655e920 in HTTPsTask_InstanceTaskCreate (p_instance=0x5657645c <Mem_Heap+28>, p_err=0xffffd654)
    at Server/Source/http-s_task.c:331
#8  0x5655c2e0 in HTTPs_InstanceStart (p_instance=0x5657645c <Mem_Heap+28>, p_err=0xffffd654) at Server/Source/http-s.c:812
#9  0x56557fc2 in main (argc=1, argv=0xffffd714) at server_app.c:105
(gdb)
TIMELINE

2023-02-28 - Vendor Disclosure
2023-06-23 - Vendor Patch Release
2023-11-14 - Public Release

Credit

Discovered by Kelly Leuschner of Cisco Talos.