CVE-2023-28379
A memory corruption vulnerability exists in the HTTP Server form boundary functionality of Weston Embedded uC-HTTP v3.01.01. A specially crafted network packet can lead to 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 v3.01.01
Weston Embedded Cesium NET 3.07.01
Silicon Labs Gecko Platform 4.3.1.0
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
9.0 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE-119 - Improper Restriction of Operations within the Bounds of a Memory Buffer
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.
When parsing the boundary string of an HTTP request, the length of that boundary string is not checked before it is used as an index into a buffer on the heap whose length is 72 bytes. If the value of len
is greater than or equal to 72 bytes, the NULL termination at [0]
could result in heap corruption.
File: http-s_req.c
1663: p_val++; /* Remove space before boundary val. */
1664: p_val = HTTP_StrGraphSrchFirst(p_val,
1665: len);
1666: len = p_field_end - p_val;
...
1672: /* Make sure to create a string. */
1673: p_conn->FormBoundaryPtr[len] = ASCII_CHAR_NULL; /* [0] */
Because of the memory layout is implemented by the uC-LIB Memory Library, this one byte overwrite results in an arbitrary allocation controlled by the attacker, which could be used to gain code execution as explained below.
When a heap object is freed using uC-LIB Memory Mem_DynPoolBlkFree
, the pointer to the next free chunk of memory within that pool is stored in the first 4 bytes of that memory block [0]
.
File: lib_mem.c
2072: void Mem_DynPoolBlkFree (MEM_DYN_POOL *p_pool,
2073: void *p_blk,
2074: LIB_ERR *p_err)
2075: {
...
2109: *((void **)p_blk) = p_pool->BlkFreePtr; /* [0] */
So, when this NULL byte overwrite occurs and the following heap block has been allocated and freed previously, this will overwrite the least significant byte of the next free pointer address. It is possible for the attacker to influence allocations such that when overwriting the least significant byte, the new pointer address will point to a buffer containing attacker controlled data. When this happens, on the next allocation of the heap pool which contains the corrupted free pointer, that same corrupt pointer will be dereferenced and stored in the pool object as the next free pointer [1]
. This dereferenced value is attacker-controlled, since the corrupted pointer now points to an attacker controlled buffer as a result of this vulnerability. On the next call to Mem_DynPoolBlkGet
, the dereferenced attacker controlled value will be the pointer, which is allocated [0]
. The result of this is that the attacker has the ability to allocate memory at an arbitrary address. The impact of an attacker being able to allocate an arbitrary address is that now the attacker can write data anywhere in the program memory space, which could lead to things like overwriting stack data or a function pointer in order to gain code execution.
File: lib_mem.c
1978: void *Mem_DynPoolBlkGet (MEM_DYN_POOL *p_pool,
1979: LIB_ERR *p_err)
1980: {
...
2014: p_blk = p_pool->BlkFreePtr; /* [0] */
2015: p_pool->BlkFreePtr = *((void **)p_blk); /* [1] */
Program received signal SIGSEGV, Segmentation fault.
0x565694ee in Mem_DynPoolBlkGet (p_pool=0x565764fc <HTTP_Heap+540>, p_err=0xffffd3ac) at uc-lib/lib_mem.c:2015
2015 p_pool->BlkFreePtr = *((void **)p_blk);
(gdb) i r
eax 0x41414141 1094795585
ecx 0x565772d9 1448571609
edx 0x3 3
ebx 0x56575f64 1448566628
esp 0xffffd360 0xffffd360
ebp 0xffffd378 0xffffd378
esi 0xf7f91000 -134672384
edi 0xf7f91000 -134672384
eip 0x565694ee 0x565694ee <Mem_DynPoolBlkGet+124>
eflags 0x10206 [ PF 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 0x565694ee in Mem_DynPoolBlkGet (p_pool=0x565764fc <HTTP_Heap+540>, p_err=0xffffd3ac) at uc-lib/lib_mem.c:2015
#1 0x56563ffa in HTTPsMem_ReqHdrGet (p_instance=0x56576380 <HTTP_Heap+160>, p_conn=0x565768ac <HTTP_Heap+1484>, hdr_field=HTTP_HDR_FIELD_ACCEPT, val_type=HTTP_HDR_VAL_TYPE_STR_DYN, p_err=0xffffd47c)
at Server/Source/http-s_mem.c:2141
#2 0x5655a2b6 in HTTPsReq_HdrParse (p_instance=0x56576380 <HTTP_Heap+160>, p_conn=0x565768ac <HTTP_Heap+1484>, p_err=0xffffd47c) at Server/Source/http-s_req.c:1780
#3 0x56558d0d in HTTPsReq_Handle (p_instance=0x56576380 <HTTP_Heap+160>, p_conn=0x565768ac <HTTP_Heap+1484>) at Server/Source/http-s_req.c:325
#4 0x5655ca3e in HTTPsConn_Process (p_instance=0x56576380 <HTTP_Heap+160>) at Server/Source/http-s_conn.c:166
#5 0x5655edc0 in HTTPsTask_InstanceTaskHandler (p_instance=0x56576380 <HTTP_Heap+160>) at Server/Source/http-s_task.c:814
#6 0x5655eb26 in HTTPsTask_InstanceTask (p_data=0x56576380 <HTTP_Heap+160>) at Server/Source/http-s_task.c:653
#7 0x565668d1 in KAL_TaskCreate (task_handle=..., p_fnct=0x5655eb01 <HTTPsTask_InstanceTask>, p_task_arg=0x56576380 <HTTP_Heap+160>, prio=17 '\021', p_cfg=0x0, p_err=0xffffd5d0)
at uc-shims/Source/kal-shim.c:59
#8 0x5655e845 in HTTPsTask_InstanceTaskCreate (p_instance=0x56576380 <HTTP_Heap+160>, p_err=0xffffd64c) at Server/Source/http-s_task.c:331
#9 0x5655c23d in HTTPs_InstanceStart (p_instance=0x56576380 <HTTP_Heap+160>, p_err=0xffffd64c) at Server/Source/http-s.c:812
#10 0x56557f01 in main (argc=1, argv=0xffffd714) at server_app.c:156
(gdb)
This vulnerability can be mitigated by disabling form and multipart form processing in your application. Disabling this requires changes to the configuration header and the instance configuration file as noted below:
File: http-s_cfg.h
147: /*
148: *********************************************************************************************************
149: * HTTP SERVER FORM CONFIGURATION
150: *
151: * Note(s) : (1) Configure HTTPs_CFG_FORM_EN to enable/disable Form processing source code.
152: *
153: * (2) Configure HTTPs_CFG_FORM_MULTIPART_EN to enable/disable multipart Form processing source code.
154: *********************************************************************************************************
155: */
156:
157: /* Configure Form processing feature (see Note #1): */
158: #define HTTPs_CFG_FORM_EN DEF_DISABLED
159: /* DEF_DISABLED Form processing DISABLED */
160: /* DEF_ENABLED Form processing ENABLED */
161:
162: /* Configure Multipart Form processing feature ... */
163: /* ... (see Note #2): */
164: #define HTTPs_CFG_FORM_MULTIPART_EN DEF_DISABLED
165: /* DEF_DISABLED Mutlipart Form processing DISABLED */
166: /* DEF_ENABLED Mutlipart Form processing ENABLED */
File: app_basic_http-s_instance_cfg.c
328: *--------------------------------------------------------------------------------------------------------
329: * INSTANCE FORM CONFIGURATION
330: *--------------------------------------------------------------------------------------------------------
331: */
332:
333: DEF_NULL, /* .FormCfgPtr : Pointer to Form Cfg Object. */
Another mitigation option is to modify the code within uC-HTTP itself by checking that the length used as the index is less than the configured size of the buffer.
diff --git a/Server/Source/http-s.h b/Server/Source/http-s.h
index a84e1db..e0880ec 100644
--- a/Server/Source/http-s.h
+++ b/Server/Source/http-s.h
@@ -450,6 +450,7 @@ typedef enum https_err {
HTTPs_ERR_REQ_HDR_POOL_LIB_FAULT,
HTTPs_ERR_REQ_HDR_DATA_TYPE_UNKNOWN,
HTTPs_ERR_REQ_BODY_FAULT,
+ HTTPs_ERR_REQ_FORM_BOUNDARY_INVALID_LEN,
HTTPs_ERR_KEY_VAL_CFG_POOL_SIZE_INV,
diff --git a/Server/Source/http-s_mem.c b/Server/Source/http-s_mem.c
index be6d3e8..851abe9 100644
--- a/Server/Source/http-s_mem.c
+++ b/Server/Source/http-s_mem.c
@@ -49,14 +49,6 @@
#define HTTPs_CFG_POOLS_INIT_NBR 1
-/*
-*********************************************************************************************************
-* FORM DEFINES
-*********************************************************************************************************
-*/
-
-#define HTTPs_FORM_BOUNDARY_STR_LEN_MAX 72u
-
/*
*********************************************************************************************************
diff --git a/Server/Source/http-s_mem.h b/Server/Source/http-s_mem.h
index dfd95b2..c2a0c2e 100644
--- a/Server/Source/http-s_mem.h
+++ b/Server/Source/http-s_mem.h
@@ -144,6 +144,14 @@ void HTTPsMem_RespHdrRelease (HTTPs_INSTANCE *
HTTPs_CONN *p_conn);
#endif
+/*
+*********************************************************************************************************
+* FORM DEFINES
+*********************************************************************************************************
+*/
+
+#define HTTPs_FORM_BOUNDARY_STR_LEN_MAX 72u
+
/*
*********************************************************************************************************
diff --git a/Server/Source/http-s_req.c b/Server/Source/http-s_req.c
index d487160..e04cd4b 100644
--- a/Server/Source/http-s_req.c
+++ b/Server/Source/http-s_req.c
@@ -1665,6 +1665,11 @@ static void HTTPsReq_HdrParse (HTTPs_INSTANCE *p_instance,
len);
len = p_field_end - p_val;
+ if (len >= HTTPs_FORM_BOUNDARY_STR_LEN_MAX) {
+ *p_err = HTTPs_ERR_REQ_FORM_BOUNDARY_INVALID_LEN;
+ return;
+ }
+
/* Copy boundary val to Conn struct. */
Str_Copy_N(p_conn->FormBoundaryPtr,
p_val,
2023-03-29 - Vendor Disclosure
2023-06-23 - Vendor Patch Release
2023-11-14 - Public Release
Discovered by Kelly Leuschner of Cisco Talos.