May 22, 2023
CVE-2023-2854
Huascar Tejeda of Pentraze Cybersecurity
A heap buffer overflow vulnerability has been discovered in Wireshark’s g_strndup function, which could potentially lead to remote code execution.
9.0 (Critical) - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
The vulnerability lies within the blf_read_apptextmessage function (found in the blf.c file), which is used by the Wireshark BLF (Binary Logging Format) plugin. The Address Sanitizer (ASAN) and GDB backtrace revealed a heap-buffer-overflow when the g_strsplit_set function is called. This function splits the string on the specified delimiters and creates an array of tokens.
In the provided backtrace, g_strsplit_set is called with text and “;” as the input parameters. If this string is carefully crafted, it could lead to arbitrary code execution when the process attempts to read or write to a memory area it doesn’t own, which is typical behavior for a heap-buffer-overflow vulnerability.
Open the trigger file using a Wireshark binary compiled with the -DENABLE_ASAN option:
$ tshark -r trigger
=================================================================
==147490==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000311440 at pc 0x7ffff745be47 bp 0x7fffffffc730 sp 0x7fffffffbed8
READ of size 17 at 0x602000311440 thread T0
#0 0x7ffff745be46 in __interceptor_strncpy ../../../../src/libsanitizer/asan/asan_interceptors.cpp:484
#1 0x7fffdfd3982b in g_strndup (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x7382b)
#2 0x7fffdfd3daba in g_strsplit_set (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x77aba)
#3 0x7fffdfa5933f in blf_read_apptextmessage /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1646
#4 0x7fffdfa5933f in blf_read_block /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1820
#5 0x7fffdfa5a79f in blf_read /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1846
#6 0x7fffdfb34583 in wtap_read /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/wtap.c:1555
#7 0x55555558eb8f in process_cap_file_single_pass /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3534
#8 0x55555558eb8f in process_cap_file /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3746
#9 0x55555558eb8f in main /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:2260
#10 0x7fffdf629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#11 0x7fffdf629e3f in __libc_start_main_impl ../csu/libc-start.c:392
#12 0x555555591754 in _start (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark+0x3d754)
0x602000311440 is located 0 bytes to the right of 16-byte region [0x602000311430,0x602000311440)
allocated by thread T0 here:
#0 0x7ffff74b4a37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x7fffdfa592c2 in blf_read_apptextmessage /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1637
#2 0x7fffdfa592c2 in blf_read_block /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1820
#3 0x7fffffffdd2f ([stack]+0x1fd2f)
...
...
=================================================================
==147490==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000311440 at pc 0x7ffff745be47 bp 0x7fffffffc730 sp 0x7fffffffbed8
READ of size 17 at 0x602000311440 thread T0
#0 0x7ffff745be46 in __interceptor_strncpy ../../../../src/libsanitizer/asan/asan_interceptors.cpp:484
#1 0x7fffdfd3982b in g_strndup (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x7382b)
#2 0x7fffdfd3daba in g_strsplit_set (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x77aba)
#3 0x7fffdfa5933f in blf_read_apptextmessage /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1646
#4 0x7fffdfa5933f in blf_read_block /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1820
#5 0x7fffdfa5a79f in blf_read /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1846
#6 0x7fffdfb34583 in wtap_read /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/wtap.c:1555
#7 0x55555558eb8f in process_cap_file_single_pass /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3534
#8 0x55555558eb8f in process_cap_file /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:3746
#9 0x55555558eb8f in main /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/tshark.c:2260
#10 0x7fffdf629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#11 0x7fffdf629e3f in __libc_start_main_impl ../csu/libc-start.c:392
#12 0x555555591754 in _start (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/tshark+0x3d754)
0x602000311440 is located 0 bytes to the right of 16-byte region [0x602000311430,0x602000311440)
allocated by thread T0 here:
#0 0x7ffff74b4a37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x7fffdfa592c2 in blf_read_apptextmessage /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1637
#2 0x7fffdfa592c2 in blf_read_block /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1820
#3 0x7fffffffdd2f ([stack]+0x1fd2f)
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/asan/asan_interceptors.cpp:484 in __interceptor_strncpy
Shadow bytes around the buggy address:
0x0c048005a230: fa fa 00 03 fa fa 00 03 fa fa 00 fa fa fa 00 02
0x0c048005a240: fa fa 00 fa fa fa 00 00 fa fa 00 00 fa fa fd fa
0x0c048005a250: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fd
0x0c048005a260: fa fa 00 05 fa fa fd fd fa fa 00 05 fa fa 00 00
0x0c048005a270: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
=>0x0c048005a280: fa fa 00 00 fa fa 00 00[fa]fa 01 fa fa fa fa fa
0x0c048005a290: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c048005a2a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c048005a2b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c048005a2c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c048005a2d0: 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
Shadow gap: cc
==147490==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 - 0x0000000000024022 (147490)
rdi - 0x0000000000024022 (147490)
rbp - 0x0000000000024022 (0x24022)
rsp - 0x00007fffffffaf00 (0x7fffffffaf00)
r8 - 0x00007fffffffafd0 (140737488334800)
r9 - 0x0000000000000000 (0)
r10 - 0x0000000000000008 (8)
r11 - 0x0000000000000246 (582)
r12 - 0x0000000000000006 (6)
r13 - 0x0000000000000016 (22)
r14 - 0x00007fffd6670000 (140736790462464)
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)
#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 0x00007ffff745be66 in __interceptor_strncpy (/lib/x86_64-linux-gnu/libasan.so.6)
at ../../../../src/libsanitizer/asan/asan_interceptors.cpp:484
#10 0x00007fffdfd3982c in g_strndup (/lib/x86_64-linux-gnu/libglib-2.0.so.0)
#11 0x00007fffdfd3dabb in g_strsplit_set (/lib/x86_64-linux-gnu/libglib-2.0.so.0)
#12 0x00007fffdfa59340 in blf_read_apptextmessage (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/libwiretap.so.13)
????: gboolean blf_read_apptextmessage(timestamp = (guint64)<optimized out>, object_length = (gint64)<optimized out>, data_start = (gint64)<optimized out>, block_start = (gint64)0, err_info = (gchar **)0x7fffffffd320, err = (int *)0x7fffffffd030, params = (blf_params_t *)0x7fffffffcd30) {
||||:
||||: /* Local reference: gchar ** tokens = <optimized out>; */
||||: /* Local reference: gchar * text = 0x602000311430 ";3eff582ae\t5148b\002\021"; */
1644:
1645: /* returns a NULL terminated array of NULL terminates strings */
1646: gchar **tokens = g_strsplit_set(text, ";", -1);
||||:
----: }
at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1646
#13 0x00007fffdfa59340 in blf_read_block (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/libwiretap.so.13)
1693: gboolean blf_read_block(params = (blf_params_t *)0x7fffffffcd30, start_pos = (gint64)0, err = (int *)0x7fffffffd030, err_info = (gchar **)0x7fffffffd320) {
||||:
||||: /* Local reference: blf_params_t * params = 0x7fffffffcd30; */
||||: /* Local reference: int * err = 0x7fffffffd030; */
||||: /* Local reference: gchar ** err_info = 0x7fffffffd320; */
||||: /* Local reference: gint64 start_pos = 0; */
1818:
1819: case BLF_OBJTYPE_APP_TEXT:
1820: if (!blf_read_apptextmessage(params, err, err_info, start_pos, start_pos + header.header_length, header.object_length, timestamp)) {
||||:
----: }
at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1820
#14 0x00007fffdfa5a7a0 in blf_read (/home/htejeda/fuzzing/wireshark/wireshark-4.0.5/build-asan/run/libwiretap.so.13)
1837: gboolean blf_read(wth = (wtap *)<optimized out>, rec = (wtap_rec *)<optimized out>, buf = (Buffer *)<optimized out>, err = (int *)<optimized out>, err_info = (gchar **)<optimized out>, data_offset = (gint64 *)0x7fffffffd3c0) {
||||:
||||: /* Local reference: wtap * wth = <optimized out>; */
||||: /* Local reference: int * err = <optimized out>; */
||||: /* Local reference: gchar ** err_info = <optimized out>; */
1844: blf_tmp.blf_data = (blf_t *)wth->priv;
1845:
1846: if (!blf_read_block(&blf_tmp, blf_tmp.blf_data->current_real_seek_pos, err, err_info)) {
||||:
----: }
at /home/htejeda/fuzzing/wireshark/wireshark-4.0.5/wiretap/blf.c:1846
#15 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 *)0x7fffffffdd30, buf = (Buffer *)0x7fffffffd4a0, err = (int *)0x7fffffffd030, err_info = (gchar **)0x7fffffffd320, offset = (gint64 *)0x7fffffffd3c0) {
||||:
||||: /* Local reference: int * err = 0x7fffffffd030; */
||||: /* Local reference: gchar ** err_info = 0x7fffffffd320; */
||||: /* Local reference: wtap * wth = 0x60f000001030; */
||||: /* Local reference: wtap_rec * rec = 0x7fffffffdd30; */
||||: /* Local reference: Buffer * buf = 0x7fffffffd4a0; */
||||: /* Local reference: gint64 * offset = 0x7fffffffd3c0; */
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
#16 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 *)0x7fffffffd050, err_info = (gchar **)0x7fffffffd320, err = (int *)0x7fffffffd030, max_write_packet_count = (int)0, max_byte_count = (gint64)0, max_packet_count = (int)0, pdh = (wtap_dumper *)0x0) {
||||:
||||: /* Local reference: int * err = 0x7fffffffd030; */
||||: /* Local reference: capture_file * cf = 0x55555563d000 <cfile>; */
||||: /* Local reference: gchar ** err_info = 0x7fffffffd320; */
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
#17 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
#18 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
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.