Loading HuntDB...

CVE-2024-6197: freeing stack buffer in utf8asn1str

Medium
C
curl
Submitted None
Reported by z2_

Vulnerability Details

Technical details and impact analysis

Free of Memory not on the Heap
Libcurl at commit [04739054cdac5a0614fb94e3655e313c03399f35](https://github.com/curl/curl/tree/04739054cdac5a0614fb94e3655e313c03399f35) contains an invalid invocation of `free()` in the function `utf8asn1str()` at [lib/vtls/x509asn1.c:397](https://github.com/curl/curl/blob/04739054cdac5a0614fb94e3655e313c03399f35/lib/vtls/x509asn1.c#L397). The relevant code can be seen below: ```c static CURLcode utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end) { // --- snip --- if(type == CURL_ASN1_UTF8_STRING) { // --- snip --- } else { while(!result && (from < end)) { char buf[4]; /* decode buffer */ // --- snip --- if(wc >= 0x00200000) { free(buf); /* Invalid char. size for target encoding. */ return CURLE_WEIRD_SERVER_REPLY; } } } } ``` `buf` is located on the stack and not the heap, which means that `buf` will be falsely treated as a heap chunk. This poses a security risk because the address of `buf` can be returned in subsequent calls to `malloc()`, which causes the stack contents at that point to be overwritten. The stack holds data that determines the control flow of the application. This can either be local variables that indirectly determine the control flow of their corresponding functions or security-critical metadata liked saved framepointers or return addresses. If an attacker manages to overwrite these kinds of stack contents he/she can gain control over the control flow of the application. # Exploit Scenario Consider the following scenario that demonstrates how to leverage the invalid `free()` to overwrite return addresses: 1. The attacker sets up a malicious server with a TLS certificate that triggers the invalid `free()` 2. An application using libcurl connects to the server and during the connect() phase parses the invalid certificate. This causes the stack address to be put into the freelist of the allocator. 3. The attacker interacts with the client in a way that causes the stack address to be returned by a `malloc()` call and used to store data from the attacker 4. Depending on the state of the stack, the attacker can now overwrite local variables, pointers or security-critical metadata. The worst case would be that a return address gets overwritten with a [ROP-chain](https://en.wikipedia.org/wiki/Return-oriented_programming) in order to gain control over the execution of the program One environment where that scenario could work out is Ubuntu bionic, where the glibc does not check whether the argument to `free()` actually refers to a valid heap chunk. # Patch The fix for this vulnerability is pretty straight forward, just remove the call to `free()`: ```diff diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c index cea88e668..ddfb65344 100644 --- a/lib/vtls/x509asn1.c +++ b/lib/vtls/x509asn1.c @@ -394,7 +394,6 @@ utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end) if(wc >= 0x00000800) { if(wc >= 0x00010000) { if(wc >= 0x00200000) { - free(buf); /* Invalid char. size for target encoding. */ return CURLE_WEIRD_SERVER_REPLY; } ``` ## Impact I assess the impact of this vulnerability to be "High" because 1. The invalid `free()` is easy to trigger since it happens during the TLS handshake 2. An overwrite of memory contents with attacker-controlled data poses a great security risk

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Submitted

Weakness

Free of Memory not on the Heap