Heap Buffer Overflow blf_read_apptextmessage Function

May 26, 2023

CVE Number

CVE-2023-2857

Credits

Huascar Tejeda of Pentraze Cybersecurity

Summary

A heap-buffer overflow vulnerability has been discovered in Wireshark’s Binary Logging Format (BLF) file processing. The vulnerability occurs in the blf_pull_logcontainer_into_memory() function in the wiretap/blf.c file. The vulnerability could be exploited by providing a maliciously crafted BLF file, which could lead to arbitrary code execution.

CVSS

9.0 (Critical) - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

Details

The overflow is triggered by a call to memcpy (displayed as __asan_memcpy in the ASAN output), copying 28 bytes into a memory region that is only 15 bytes large. This region was allocated in blf_pull_logcontainer_into_memory using calloc at wiretap/blf.c:499.

After the overflow, the program execution continues until it attempts to allocate memory with malloc in wmem_strdup_printf (as part of error handling), causing a crash with the message malloc(): corrupted top size.

Steps to reproduce:

Open the trigger file using a Wireshark binary compiled with the -DENABLE_ASAN option:

$ tshark -r trigger
=================================================================
==264046==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffffcd21 at pc 0x7fffdfaf46cd bp 0x7fffffffca80 sp 0x7fffffffca70
READ of size 1 at 0x7fffffffcd21 thread T0
    #0 0x7fffdfaf46cc in parse_vms_packet /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/vms.c:383
    #1 0x7fffdfb34583 in wtap_read /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/wtap.c:1555
    #2 0x55555558eb8f in process_cap_file_single_pass /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3534
    #3 0x55555558eb8f in process_cap_file /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3746
    #4 0x55555558eb8f in main /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:2260
    #5 0x7fffdf629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #6 0x7fffdf629e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #7 0x555555591754 in _start (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark+0x3d754)

Address 0x7fffffffcd21 is located in stack of thread T0 at offset 497 in frame
    #0 0x7fffdfaf37ff in parse_vms_packet /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/vms.c:322

  This frame has 8 object(s):
    [48, 52) 'pkt_len' (line 325)
    [64, 68) 'pktnum' (line 326)
    [80, 84) 'csec' (line 327)
    [96, 104) 'endp' (line 331)
    [128, 184) 'tm' (line 328)
    [224, 227) 'lbuf' (line 504)
    [240, 244) 'mon' (line 329)
    [256, 497) 'line' (line 323) <== Memory access at offset 497 overflows this variable
...
...

ASAN

=================================================================
==264046==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffffcd21 at pc 0x7fffdfaf46cd bp 0x7fffffffca80 sp 0x7fffffffca70
READ of size 1 at 0x7fffffffcd21 thread T0
    #0 0x7fffdfaf46cc in parse_vms_packet /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/vms.c:383
    #1 0x7fffdfb34583 in wtap_read /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/wtap.c:1555
    #2 0x55555558eb8f in process_cap_file_single_pass /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3534
    #3 0x55555558eb8f in process_cap_file /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3746
    #4 0x55555558eb8f in main /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:2260
    #5 0x7fffdf629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #6 0x7fffdf629e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #7 0x555555591754 in _start (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark+0x3d754)

Address 0x7fffffffcd21 is located in stack of thread T0 at offset 497 in frame
    #0 0x7fffdfaf37ff in parse_vms_packet /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/vms.c:322

  This frame has 8 object(s):
    [48, 52) 'pkt_len' (line 325)
    [64, 68) 'pktnum' (line 326)
    [80, 84) 'csec' (line 327)
    [96, 104) 'endp' (line 331)
    [128, 184) 'tm' (line 328)
    [224, 227) 'lbuf' (line 504)
    [240, 244) 'mon' (line 329)
    [256, 497) 'line' (line 323) <== Memory access at offset 497 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)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/vms.c:383 in parse_vms_packet
Shadow bytes around the buggy address:
  0x10007fff7950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7960: 00 00 00 00 00 00 f1 f1 f1 f1 f1 f1 04 f2 04 f2
  0x10007fff7970: 04 f2 00 f2 f2 f2 00 00 00 00 00 00 00 f2 f2 f2
  0x10007fff7980: f2 f2 03 f2 04 f2 00 00 00 00 00 00 00 00 00 00
  0x10007fff7990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007fff79a0: 00 00 00 00[01]f3 f3 f3 f3 f3 f3 f3 f3 f3 00 00
  0x10007fff79b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff79c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff79d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff79e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff79f0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
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
  Shadow gap:              cc
==264046==ABORTING

Crash context:
Execution stopped here ==> 0x00007fffdf696a7c: mov    r13d,eax

Register info:
   rax - 0x0000000000000000 (0)
   rbx - 0x00007ffff72d5a80 (140737340332672)
   rcx - 0x00007fffdf696a7c (140736941615740)
   rdx - 0x0000000000000006 (6)
   rsi - 0x000000000004076e (264046)
   rdi - 0x000000000004076e (264046)
   rbp - 0x000000000004076e (0x4076e)
   rsp - 0x00007fffffffbab0 (0x7fffffffbab0)
    r8 - 0x00007fffffffbb80 (140737488337792)
    r9 - 0x0000000000000000 (0)
   r10 - 0x0000000000000008 (8)
   r11 - 0x0000000000000246 (582)
   r12 - 0x0000000000000006 (6)
   r13 - 0x0000000000000016 (22)
   r14 - 0x00007fffc6601000 (140736521572352)
   r15 - 0x0000000000010000 (65536)
   rip - 0x00007fffdf696a7c (0x7fffdf696a7c <__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)

GDB Backtrace

#0  0x00007fffdf696a7c in __pthread_kill_implementation (/lib/x86_64-linux-gnu/libc.so.6)
                       at ./nptl/pthread_kill.c:44

#1  0x00007fffdf696a7c in __pthread_kill_internal (/lib/x86_64-linux-gnu/libc.so.6)
                       at ./nptl/pthread_kill.c:78

#2  0x00007fffdf696a7c in __GI___pthread_kill (/lib/x86_64-linux-gnu/libc.so.6)
                       at ./nptl/pthread_kill.c:89

#3  0x00007fffdf642476 in __GI_raise (/lib/x86_64-linux-gnu/libc.so.6)
                       at ../sysdeps/posix/raise.c:26

#4  0x00007fffdf6287f3 in __GI_abort (/lib/x86_64-linux-gnu/libc.so.6)
                       at ./stdlib/abort.c:79

#5  0x00007ffff74d26f2 in __sanitizer::Abort (/lib/x86_64-linux-gnu/libasan.so.6)
                       at ../../../../src/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:151

#6  0x00007ffff74de2ac in __sanitizer::Die (/lib/x86_64-linux-gnu/libasan.so.6)
                       at ../../../../src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:58

#7  0x00007ffff74bd75c in __asan::ScopedInErrorReport::~ScopedInErrorReport (/lib/x86_64-linux-gnu/libasan.so.6)
                       at ../../../../src/libsanitizer/asan/asan_report.cpp:190

#8  0x00007ffff74bcff5 in __asan::ReportGenericError (/lib/x86_64-linux-gnu/libasan.so.6)
                       at ../../../../src/libsanitizer/asan/asan_report.cpp:478

#9  0x00007ffff74bdadb in __asan::__asan_report_load1 (/lib/x86_64-linux-gnu/libasan.so.6)
                       at ../../../../src/libsanitizer/asan/asan_rtl.cpp:118

#10 0x00007fffdfaf46cd in parse_vms_packet (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/libwiretap.so.13)
                       321: gboolean parse_vms_packet(fh = (FILE_T)0x6120000028c0, rec = (wtap_rec *)<optimized out>, buf = (Buffer *)<optimized out>, err = (int *)<optimized out>, err_info = (gchar **)<optimized out>) {
                       |||:
                       |||: /* Local reference: gchar * p = 0x7fffffffcd21 ""; */
                       381:         if ( (! pkt_len) && (p = strstr(line, "Length"))) {
                       382:             p += sizeof("Length ");
                       383:             while (*p && ! g_ascii_isdigit(*p))
                       |||:
                       ---: }
                       at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/vms.c:383

#11 0x00007fffdfb34584 in wtap_read (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/libwiretap.so.13)
                       1545: gboolean wtap_read(wth = (wtap *)0x60f000001030, rec = (wtap_rec *)0x7fffffffdd20, buf = (Buffer *)0x7fffffffd490, err = (int *)0x7fffffffd020, err_info = (gchar **)0x7fffffffd310, offset = (gint64 *)0x7fffffffd3b0) {
                       ||||:
                       ||||: /* Local reference: int * err = 0x7fffffffd020; */
                       ||||: /* Local reference: gchar ** err_info = 0x7fffffffd310; */
                       ||||: /* Local reference: wtap * wth = 0x60f000001030; */
                       ||||: /* Local reference: wtap_rec * rec = 0x7fffffffdd20; */
                       ||||: /* Local reference: Buffer * buf = 0x7fffffffd490; */
                       ||||: /* Local reference: gint64 * offset = 0x7fffffffd3b0; */
                       1553: 	*err = 0;
                       1554: 	*err_info = NULL;
                       1555: 	if (!wth->subtype_read(wth, rec, buf, err, err_info, offset)) {
                       ||||:
                       ----: }
                       at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/wtap.c:1555

#12 0x000055555558eb90 in process_cap_file_single_pass (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark)
                       ????: pass_status_t process_cap_file_single_pass(cf = (capture_file *)0x55555563d000 <cfile>, err_framenum = (volatile guint32 *)0x7fffffffd040, err_info = (gchar **)0x7fffffffd310, err = (int *)0x7fffffffd020, max_write_packet_count = (int)0, max_byte_count = (gint64)0, max_packet_count = (int)0, pdh = (wtap_dumper *)0x0) {
                       ||||:
                       ||||: /* Local reference: int * err = 0x7fffffffd020; */
                       ||||: /* Local reference: capture_file * cf = 0x55555563d000 <cfile>; */
                       ||||: /* Local reference: gchar ** err_info = 0x7fffffffd310; */
                       3532: 
                       3533:     *err = 0;
                       3534:     while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
                       ||||:
                       ----: }
                       at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3534

#13 0x000055555558eb90 in process_cap_file (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark)
                       ????: process_file_status_t process_cap_file(cf = (capture_file *)0x55555563d000 <cfile>, max_write_packet_count = (int)0, max_byte_count = (gint64)0, max_packet_count = (int)0, out_file_name_res = (gboolean)0, out_file_type = (int)0, save_file = (char *)0x0) {
                       ||||:
                       ||||: /* Local reference: pass_status_t first_pass_status = PASS_SUCCEEDED; */
                       ||||: /* Local reference: pass_status_t second_pass_status = <optimized out>; */
                       ||||: /* Local reference: wtap_dumper * pdh = 0x0; */
                       ||||: /* Local reference: capture_file * cf = 0x55555563d000 <cfile>; */
                       3744: 
                       3745:         first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
                       3746:         second_pass_status = process_cap_file_single_pass(cf, pdh,
                       ||||:
                       ----: }
                       at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3746

#14 0x000055555558eb90 in main (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark)
                        789: int main(argc = (int)<optimized out>, argv = (char **)<optimized out>) {
                       ||||:
                       2258:         ws_debug("tshark: invoking process_cap_file() to process the packets");
                       2259:         TRY {
                       2260:             status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
                       ||||:
                       ----: }
                       at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:2260

¿Ver el sitio en español?