CVE-2023-45318
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.
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
uC-HTTP - https://weston-embedded.com/micrium/overview Gecko Platform - https://www.silabs.com/developers/gecko-software-development-kit
10.0 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE-122 - Heap-based Buffer Overflow
µ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);
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)
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;
2023-10-26 - Vendor Disclosure
2024-02-14 - Vendor Patch Release
2024-02-20 - Public Release
Discovered by Kelly Patterson of Cisco Talos.