Back to the articles

CVE-2022-24942 Heap-based buffer overflow in Silicon Labs Gecko SDK

picture of the author
Attila Szász
February 14, 2023 8 mins read
CVE-2022-24942 Heap-based buffer overflow in Silicon Labs Gecko SDK

Table of contents

  1. Disclosure timeline
  2. Affected products
  3. Product URLs
  4. What is Micrium uC-HTTP?
  5. Summary
  6. Details
  7. Discovery
  8. Testing
  9. Acknowledgments
  10. Give it a try

Disclaimer: The following vulnerability was detected by BugProve's security research team conducting analysis on publicly available products/firmware. Firmware uploaded by users to BugProve's platform have no connection with any of our own research projects. For more information, check out our Vulnerability Disclosure Policy.

Disclosure timeline

May 26, 2022: BugProve reports the issue to Silicon Labs.
May 26, 2022: Silicon Labs acknowledges the issue.
Aug 3, 2022: Silicon Labs officially confirms the issue with a fix.
Aug 13, 2022: Silicon Labs releases advisory with version 4.1.1.0 of Gecko SDK.
Sep 16, 2022: Silicon Labs allocates CVE-2022-24942 for the vulnerability after resolving technical issues with their CVE Services systems.
Feb 15, 2023: Release of this write-up.

Affected products

  • Micrium uC-HTTP V3.01.01
  • Silicon Labs Gecko SDK up to 4.0.2

Product URLs

https://www.silabs.com/developers/micrium

https://github.com/SiliconLabs/gecko_sdk

What is Micrium uC-HTTP?

µC/OS is a full-featured embedded operating system originally developed by Micriµm™, it is provided as part of Silicon Lab’s Gecko SDK. In addition to the two highly popular kernels, µC/OS features support for TCP/IP, USB-Device, USB-Host, and Modbus, as well as a robust File System. The uC-HTTP implementation is used on embedded systems that are running the µC/OS II or µC/OS III RTOS kernels. The HTTP server included in it supports many HTTP features, enabling embedded systems developers to rely on it for a variety of use cases in their design.

Summary

A heap based buffer overflow vulnerability exists in the HTTP Server functionality of Micrium uC-HTTP 3.01.01. A specially crafted HTTP request can lead to remote code execution. An attacker can send an HTTP request to trigger this vulnerability.

Details

The HTTP server supports multipart requests. Following HTML 4.01 Specification and RFC2045 and EFC2388, the implementation checks the presence of a boundary when the Content-Type header is multipart/form-data and stores it in p_conn->FormBoundaryPtr However, when calculating the size of the string segment to be copied, the implementation does not check the resulting value against the maximum length the allocated buffer can hold (HTTPs_FORM_BOUNDARY_STR_LEN_MAX) The relevant piece of code is located in platform/micrium_os/net/source/http/server/http_server_req.c (function HTTPsReq_HdrParse):

static void HTTPsReq_HdrParse(HTTPs_INSTANCE *p_instance,
              HTTPs_CONN   *p_conn,
              HTTPs_ERR   *p_err)
{
 CPU_CHAR       *p_field;
 CPU_CHAR       *p_field_end;
 CPU_CHAR       *p_val;

[..]

            p_val = Str_Char_N(p_val, len, ASCII_CHAR_EQUALS_SIGN);    
            if (p_val == DEF_NULL) {
             *p_err = HTTPs_ERR_REQ_FORMAT_INVALID;
             return;
            }
            p_val++;                // Remove space before boundary val.
            p_val = HTTP_StrGraphSrchFirst(p_val,
                            len);
            len = p_field_end - p_val;
          //                     Copy boundary val to Conn struct.
          Str_Copy_N(p_conn->FormBoundaryPtr,
                p_val,
               len);
          //                     Make sure to create a string.
          p_conn->FormBoundaryPtr[len] = ASCII_CHAR_NULL;
          p_conn->FormBoundaryLen = len;

Discovery

We found the vulnerability while testing the compatibility of our binary analysis engine PRIS™ with Silicon Labs’ Gecko SDK. We selected uC-HTTP binaries for analysis since we suspected that most of the alerts raised by PRIS were going to be easy candidates for our taint analysis component to reason about in terms of correlating function parameters to pointers to networking data.

In order to make our analysis work, we had to implement support for the special libc used in Micrium (https://github.com/weston-embedded/uC-LIB/tree/b3a8be2e81bf24cf5722eec632b1c0aa16b6112e)

After that, we left our code running on the different binaries and inspected the results. The file http-s_req.o in charge of handling HTTP requests raised an alert that indicated that a function semantically equivalent to strncpy() was called on tainted data. Moreover, the ‘num’ parameter of the call was incorrectly calculated based on pointer arithmetic of an attacker-controlled string without further boundary checks:

The data flow dependencies for the vulnerable call site can be summarized as follows (the build used here is ARMv7):

Data Flow Dependencies
Data Flow Dependencies

Here, you can see that the definition at 0x401109 is a tainted pointer expression. In fact, the input pointer is the result of the HTTP parser trying to find the end of the multipart boundary value, essentially reducing strncpy() to an unsafe strcpy().

Using Ghidra, and shifting all addresses by one due to Thumb mode, it can be verified that the subs instruction highlighted below is the one responsible for this runtime behavior.

Vulnerable Code
Vulnerable Code

We verified the issue by sending a large boundary value string to the HTTP server that crashed it.

Testing

Using a build of the code with address sanitizer enabled (x86-64 for convenience), the vulnerability can be also demonstrated using specially crafted input:

==31170==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60700000032f at pc 0x55b0167b85c8 bp 0x7ffca0e2aa60 sp 0x7ffca0e2aa50

WRITE of size 1 at 0x60700000032f thread T0
  \#0 0x55b0167b85c7 in HTTPsReq_HdrParse (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0x95c7)
  \#1 0x55b0167b37ad in HTTPsReq_Handle (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0x47ad)
  \#2 0x55b0167be5ec in main (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0xf5ec)
  \#3 0x7ffbef679bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
  \#4 0x55b0167b2969 in _start (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0x3969)

0x60700000032f is located 15 bytes inside of 1094795585-byte region [0x607000000320,0x607041414461)
==31170==AddressSanitizer CHECK failed: ../../../../src/libsanitizer/asan/asan_descriptions.cc:176 "((res.trace)) != (0)" (0x0, 0x0)
  \#0 0x7ffbefb32bf2 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe9bf2)
  \#1 0x7ffbefb51575 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x108575)
  \#2 0x7ffbefa7646c (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x2d46c)
  \#3 0x7ffbefa77838 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x2e838)
  \#4 0x7ffbefa7a8db (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x318db)
  \#5 0x7ffbefb3254f (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe954f)
  \#6 0x7ffbefb334b9 in __asan_report_store1 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xea4b9)
  \#7 0x55b0167b85c7 in HTTPsReq_HdrParse (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0x95c7)
  \#8 0x55b0167b37ad in HTTPsReq_Handle (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0x47ad)
  \#9 0x55b0167be5ec in main (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0xf5ec)
  \#10 0x7ffbef679bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
  \#11 0x55b0167b2969 in _start (/home/ubuntu/sbox/uC-HTTP/Server/Source/a.out+0x3969) 

As one can verify, this is a straightforward heap-based buffer overflow, potentially allowing for remote code execution on systems that don’t feature any additional mitigations.

Acknowledgments

The vulnerability was found by Attila Szasz at BugProve, using BugProve PRIS™.

Give it a try

We have just launched our automated firmware analysis tool, BugProve, to reduce the time spent on embedded systems security research and binary reverse engineering, and to increase the overall security of IoT products on the market. It features PRIS™, a code analysis engine with similar capabilities as highlighted above, supporting standard libc’s on ARMv7, MIPS, MIPS64, ARMv8, x86, and PPC (for the complete list, please refer to BugProve Knowledge Hub).

At a high-level BugProve gives you the following:

  • SCA and CVE lookup for open-source components used on the system.
  • Static binary code analysis and concolic analysis, which is in the middle ground between SAST and using firmware emulation for security testing.
  • A range of security checks only applicable to embedded firmware, not covered by any of the SCA and SAST tools out there.
  • Our findings and security alerts are comparable to the results of leading SAST solutions, but we perform the analysis on binaries without access to source code, offering visibility into security issues hiding in the SDK in use, tackling some of the supply chain risks. (We have pending CVEs affecting SoC vendors that you know.)
  • Better precision in dependency scanning, better file system extraction, re-assembly, and better cryptographic analysis than existing open-source tooling.
  • AI-assisted vulnerability explanations and remediation recommendations.
  • Easy-to-share reporting via live links or PDF exports.

We offer a Free Plan, give it a try now!

Was it worth your time?

Sign up for our newsletter to receive articles like this in your inbox 1-2 times per month.