Talos Vulnerability Report

TALOS-2023-1843

Weston Embedded uC-HTTP HTTP Server heap-based buffer overflow vulnerability

February 20, 2024
CVE Number

CVE-2023-45318

SUMMARY

A heap-based buffer overflow vulnerability exists in the HTTP Server functionality of Weston Embedded uC-HTTP git commit 80d4004. A specially crafted network packet 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 git commit 80d4004
Silicon Labs Gecko Platform Silicon Labs Gecko Platform 4.3.2.0

PRODUCT URLS

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

CVSSv3 SCORE

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

CWE

CWE-122 - Heap-based Buffer Overflow

DETAILS

µC/HTTP-server is a versatile web server component in Weston Embedded’s uCOS real-time operating system. It can be used as a typical webserver to store and serve web pages or as a web service for fetching and modifying web resources. It is compatible with major browsers, and supports multiple instances on different TCP ports, allowing for different security configurations. With the ability to start and stop instances at runtime, handle multiple connections simultaneously, and define custom “hook” functions for extending functionality, µC/HTTP-server offers flexibility and efficient performance for web server applications in embedded systems.

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], an integer underflow condition will occur within the internal variable used to store the remaining length of the receive buffer.

The problem occurs because the value skipped_chars is subtracted from p_conn->RxBufLenRem twice: first at [3] and then again at [4]. This is because the value calculated with (p_protocol_ver_end - p_conn->RxBufPtr) includes the skipped characters. These skipped characters’ lengths have already been subtracted, since p_conn->RxBufPtr points to the beginning of the buffer, not the beginning of the protocol version string. Therefore, if the number of skipped characters is larger than the remaining characters after the CRLF is found at [2], p_conn->RxBufLenRem will be underflowed at [4].

File: http-s_req.c
1361: static  void  HTTPsReq_ProtocolVerParse (HTTPs_INSTANCE  *p_instance,
1362:                                          HTTPs_CONN      *p_conn,
1363:                                          HTTPs_ERR       *p_err)
1364: {
...
1384:     p_protocol_ver_start = HTTP_StrGraphSrchFirst(p_conn->RxBufPtr, len);     /* [1] p_protocol_ver_start advances to the first character */ 
1385:     if (p_protocol_ver_start == DEF_NULL) {                                   /* ... [1] between 0x21 - 0x7e */
1386:        *p_err = HTTPs_ERR_REQ_FORMAT_INVALID;
1387:         return;
1388:     }
1389: 
1390:     skipped_chars        = p_protocol_ver_start - p_conn->RxBufPtr;
1391: 
1392:     len                 -= skipped_chars;                       /* Disregard illegal, non-printable ASCII characters.   */
1393:                                                                 /* Find the end of the request line.                    */
1394:     p_protocol_ver_end   = Str_Str_N(p_protocol_ver_start, STR_CR_LF, len);   /* [2] */
1395:                                                                 /* Update RxBufLenRem to reflect nbr of skipped chars.  */
1396:     p_conn->RxBufLenRem -= skipped_chars;                       /* [3] */
...
1446:                                                                 /* Update the RxBuf ptr.                                */
1447:     p_conn->RxBufLenRem      -= (p_protocol_ver_end - p_conn->RxBufPtr) + 2;      /* [4] */
1448:     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]. This 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.

File: http-s_sock.c
659: CPU_BOOLEAN  HTTPsSock_ConnDataRx (HTTPs_INSTANCE  *p_instance,
660:                                    HTTPs_CONN      *p_conn)
661: {
...
675:     if ((p_conn->RxBufLenRem > 0) &&
676:         (p_conn->RxBufPtr   != p_conn->BufPtr)) {               /* If data is still present in the rx buf.              */
677:                                                                 /* Move rem data to the beginning of the rx buf.        */
678:         Mem_Copy(p_conn->BufPtr, p_conn->RxBufPtr, p_conn->RxBufLenRem);   /* [1] */
679:     }
680: 
681:     p_buf   = p_conn->BufPtr + p_conn->RxBufLenRem;            /* [2] */
682:     buf_len = p_conn->BufLen - p_conn->RxBufLenRem;
683: 
684:     if (buf_len == 0) {
685:         rtn_val = DEF_OK;
686:         goto exit;
687:     }
688: 
689:     addr_len_client = sizeof(p_conn->ClientAddr);
690:     rx_len = (CPU_INT16U)NetSock_RxDataFrom(        p_conn->SockID,
691:                                             (void *)p_buf,
692:                                                     buf_len,
693:                                                     NET_SOCK_FLAG_NO_BLOCK,
694:                                                    &p_conn->ClientAddr,
695:                                                    &addr_len_client,
696:                                                     DEF_NULL,
697:                                                     DEF_NULL,
698:                                                     DEF_NULL,
699:                                                    &err);

Crash Information

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r
eax            0x41414141          1094795585
ecx            0x0                 0
edx            0x56586dbc          1448635836
ebx            0x56575f64          1448566628
esp            0xffffd15c          0xffffd15c
ebp            0xffffd178          0xffffd178
esi            0xf7f8e000          -134684672
edi            0xf7f8e000          -134684672
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
(gdb) bt
#0  0x41414141 in ?? ()
#1  0x56569bfc in HTTPs_ConnCloseHook (p_instance=0x5657643c <Mem_Heap+28>, p_conn=0x56576968 <Mem_Heap+1352>,
    p_hook_cfg=0x0) at poc/protocolVerOverflow2/sharedFiles/app_basic_http-s_hooks.c:1299
#2  0x5655c34e in HTTPsConn_Close (p_instance=0x5657643c <Mem_Heap+28>, p_conn=0x56576968 <Mem_Heap+1352>)
    at Server/Source/http-s_conn.c:334
#3  0x5655c073 in HTTPsConn_Process (p_instance=0x5657643c <Mem_Heap+28>) at Server/Source/http-s_conn.c:150
#4  0x5655e433 in HTTPsTask_InstanceTaskHandler (p_instance=0x5657643c <Mem_Heap+28>)
    at Server/Source/http-s_task.c:814
#5  0x5655e199 in HTTPsTask_InstanceTask (p_data=0x5657643c <Mem_Heap+28>) at Server/Source/http-s_task.c:653
#6  0x56565f44 in KAL_TaskCreate (task_handle=..., p_fnct=0x5655e174 <HTTPsTask_InstanceTask>,
    p_task_arg=0x5657643c <Mem_Heap+28>, prio=17 '\021', p_cfg=0x0, p_err=0xffffd2e0) at uc-shims/Source/kal-shim.c:59
#7  0x5655deb8 in HTTPsTask_InstanceTaskCreate (p_instance=0x5657643c <Mem_Heap+28>, p_err=0xffffd354)
    at Server/Source/http-s_task.c:331
#8  0x5655b8b0 in HTTPs_InstanceStart (p_instance=0x5657643c <Mem_Heap+28>, p_err=0xffffd354)
    at Server/Source/http-s.c:812
#9  0x5656924d in main (argc=1, argv=0xffffd414) at server_app.c:118
(gdb)

Mitigation

The only mitigation for this vulnerability is to modify the code within uC-HTTP itself to correctly update the p_conn->RxBufLenRem value.

diff --git a/Server/Source/http-s_req.c b/Server/Source/http-s_req.c
index d0c2630..201fba2 100644
--- a/Server/Source/http-s_req.c
+++ b/Server/Source/http-s_req.c
@@ -1444,7 +1444,7 @@ static  void  HTTPsReq_ProtocolVerParse (HTTPs_INSTANCE  *p_instance,
            return;
    }
                                                                /* Update the RxBuf ptr.                                */
-    p_conn->RxBufLenRem      -= (p_protocol_ver_end - p_conn->RxBufPtr) + 2;
+    p_conn->RxBufLenRem      -= len + 2;
    p_conn->RxBufPtr          =  p_protocol_ver_end + 2;

    *p_err = HTTPs_ERR_NONE;
TIMELINE

2023-10-26 - Vendor Disclosure
2024-02-14 - Vendor Patch Release
2024-02-20 - Public Release

Credit

Discovered by Kelly Patterson of Cisco Talos.