Talos Vulnerability Report

TALOS-2023-1733

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

November 14, 2023
CVE Number

CVE-2023-27882

SUMMARY

A heap-based buffer overflow 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.

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.

When parsing the boundary string of an HTTP request, the length of that boundary string is not checked before it is copied to a buffer on the heap with a length of 72 bytes. The calculated value of len is not checked before the call to Str_Copy_N [0].

File: http-s_req.c
1661:                                               p_val++;          /* Remove space before boundary val.                    */
1662:                                               p_val = HTTP_StrGraphSrchFirst(p_val,
1663:                                                                              len);
1664:                                               len   = p_field_end - p_val;
1665: 
1666:                                                                 /* Copy boundary val to Conn struct.                    */
1667:                                               Str_Copy_N(p_conn->FormBoundaryPtr,                         /* [0] */
1668:                                                          p_val,
1669:                                                          len);

Because of the memory layout implemented by the uC-LIB Memory Library, this buffer overflow 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 buffer overflow occurs and the following heap block has been allocated and freed previously, this will overwrite the next free pointer address. On the next allocation of the heap pool that contains the overwritten address, that overwritten address will be dereferenced and stored in the pool object as the next free pointer [1]. The attacker can choose where to point the overwritten address anywhere in the address space of the program, including a packet containing attacker-supplied data. 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] */

Crash Information

Program received signal SIGSEGV, Segmentation fault.
0x5656942a in Mem_DynPoolBlkGet (p_pool=0x56576578 <Mem_Heap+408>, p_err=0xffffd3bc) at uc-lib/lib_mem.c:2015
2015	        p_pool->BlkFreePtr = *((void **)p_blk);
(gdb) i r
eax            0x41414141          1094795585
ecx            0x56577223          1448571427
edx            0x2                 2
ebx            0x56575f64          1448566628
esp            0xffffd370          0xffffd370
ebp            0xffffd388          0xffffd388
esi            0xf7f91000          -134672384
edi            0xf7f91000          -134672384
eip            0x5656942a          0x5656942a <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  0x5656942a in Mem_DynPoolBlkGet (p_pool=0x56576578 <Mem_Heap+408>, p_err=0xffffd3bc)
    at uc-lib/lib_mem.c:2015
#1  0x56563f36 in HTTPsMem_ReqHdrGet (p_instance=0x565763fc <Mem_Heap+28>, 
    p_conn=0x56576928 <Mem_Heap+1352>, hdr_field=HTTP_HDR_FIELD_ACCEPT_ENCODING, 
    val_type=HTTP_HDR_VAL_TYPE_STR_DYN, p_err=0xffffd48c) at Server/Source/http-s_mem.c:2141
#2  0x5655a1f2 in HTTPsReq_HdrParse (p_instance=0x565763fc <Mem_Heap+28>, p_conn=0x56576928 <Mem_Heap+1352>, 
    p_err=0xffffd48c) at Server/Source/http-s_req.c:1780
#3  0x56558c49 in HTTPsReq_Handle (p_instance=0x565763fc <Mem_Heap+28>, p_conn=0x56576928 <Mem_Heap+1352>)
    at Server/Source/http-s_req.c:325
#4  0x5655c97a in HTTPsConn_Process (p_instance=0x565763fc <Mem_Heap+28>) at Server/Source/http-s_conn.c:166
#5  0x5655ecfc in HTTPsTask_InstanceTaskHandler (p_instance=0x565763fc <Mem_Heap+28>)
    at Server/Source/http-s_task.c:814
#6  0x5655ea62 in HTTPsTask_InstanceTask (p_data=0x565763fc <Mem_Heap+28>) at Server/Source/http-s_task.c:653
#7  0x5656680d in KAL_TaskCreate (task_handle=..., p_fnct=0x5655ea3d <HTTPsTask_InstanceTask>, 
    p_task_arg=0x565763fc <Mem_Heap+28>, prio=17 '\021', p_cfg=0x0, p_err=0xffffd5e0)
    at uc-shims/Source/kal-shim.c:59
#8  0x5655e781 in HTTPsTask_InstanceTaskCreate (p_instance=0x565763fc <Mem_Heap+28>, p_err=0xffffd654)
    at Server/Source/http-s_task.c:331
#9  0x5655c179 in HTTPs_InstanceStart (p_instance=0x565763fc <Mem_Heap+28>, p_err=0xffffd654)
    at Server/Source/http-s.c:812
#10 0x56557e2b in main (argc=1, argv=0xffffd714) at server_app.c:118

Mitigation

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 passing the size used to allocate the buffer FormBoundaryPtr to the size parameter of Str_Copy_N.

diff --git a/Server/Source/http-s_mem.c b/Server/Source/http-s_mem.c
index be6d3e8..a955963 100644
--- a/Server/Source/http-s_mem.c
+++ b/Server/Source/http-s_mem.c
@@ -49,15 +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..fedcf47 100644
--- a/Server/Source/http-s_req.c
+++ b/Server/Source/http-s_req.c
@@ -1668,7 +1668,7 @@ static  void  HTTPsReq_HdrParse (HTTPs_INSTANCE  *p_instance,
                                                                /* Copy boundary val to Conn struct.                    */
                                            Str_Copy_N(p_conn->FormBoundaryPtr,
                                                        p_val,
-                                                         len);
+                                                         HTTPs_FORM_BOUNDARY_STR_LEN_MAX);
                                                                /* Make sure to create a string.                        */
                                            p_conn->FormBoundaryPtr[len] = ASCII_CHAR_NULL;
TIMELINE

2023-03-29 - Vendor Disclosure
2023-06-23 - Vendor Patch Release
2023-11-14 - Public Release

Credit

Discovered by Kelly Leuschner of Cisco Talos.