Summary
OBS (Open Broadcaster Software) is a well-known open source and cross platform software for screen recording and streaming. Unfortunately, a crafted GIF file with malicious LZW compressed data may trigger a heap overflow bug in the OBS image parser library after commit 13890a46e6efc14a64ab5ee4f539d3a8607837a0 in Jan 2016.
Severity
High - an attacker could exploit this to write data beyond the allocated boundaries of memory on the heap.
Proof of Concept
The OBS heap overflow bug recorded by OBS: video
When applying the image source with the malicious GIF file in Ubuntu, OBS will crash immediately. Core dump reports libc tcache heap corruption:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 tcache_get (tc_idx=<optimized out>) at ./malloc/malloc.c:3196
3196 ./malloc/malloc.c: No such file or directory.
[Current thread is 1 (Thread 0xffff5ee2d480 (LWP 17380))]
gef➤ bt
#0 tcache_get (tc_idx=<optimized out>) at ./malloc/malloc.c:3196
#1 __GI___libc_malloc (bytes=0x3) at ./malloc/malloc.c:3313
#2 0x0000ffffb36aeb70 in av_strdup () at /lib/aarch64-linux-gnu/libavutil.so.56
#3 0x0000ffffb36b0df0 in av_opt_set_defaults2 () at /lib/aarch64-linux-gnu/libavutil.so.56
#4 0x0000ffffb3530038 in avformat_alloc_context () at /lib/aarch64-linux-gnu/libavformat.so.58
#5 0x0000ffff62fc6e80 in () at /usr//lib/aarch64-linux-gnu/obs-plugins/obs-ffmpeg.so
#6 0x0000ffffb158d5c8 in start_thread (arg=0x0) at ./nptl/pthread_create.c:442
#7 0x0000ffffb15f5edc in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:79
Further Analysis
By using LD_PRELOAD=/usr/aarch64-linux-gnu/lib/libasan.so.6.0.0 obs command, it appears that the heap overflow happens in libobs module:
==30002==ERROR: AddressSanitizer: SEGV on unknown address 0xffff96210000 (pc 0xffffb0df54dc bp 0xffff896c1600 sp 0xffff896c1600 T11)
==30002==The signal is caused by a WRITE memory access.
#0 0xffffb0df54dc (/lib/aarch64-linux-gnu/libobs.so.0+0x254dc)
#1 0xffffb0dffb5c (/lib/aarch64-linux-gnu/libobs.so.0+0x2fb5c)
#2 0xffffb0e008e4 in gs_image_file3_init (/lib/aarch64-linux-gnu/libobs.so.0+0x308e4)
#3 0xffff97cd37cc (/usr//lib/aarch64-linux-gnu/obs-plugins/image-source.so+0x37cc)
#4 0xffffb0e84fc4 (/lib/aarch64-linux-gnu/libobs.so.0+0xb4fc4)
#5 0xffffafddd5c4 in start_thread nptl/pthread_create.c:442
#6 0xffffafe45ed8 (/lib/aarch64-linux-gnu/libc.so.6+0xe5ed8)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/aarch64-linux-gnu/libobs.so.0+0x254dc)
Thread T11 created by T0 here:
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.
The corruption happens in gif_next_LZW (libobs/graphics/libnsgif/libnsgif.c), and the libnsgif is an open source project by NetSurf Browser (https://www.netsurf-browser.org/projects/libnsgif/). A further investigation shows that the OBS project ported libnsgif code in Jan 2016 but no one patches known security issues later on. As a result, the OBS is subject to CVE-2015-7505 and CVE-2015-7506 (OOB write and read in .bss section).
However, the OBS project also makes some changes to the libnsgif code. Instead of writing out-of-bounds or reading out-of-bounds in the .bss area, now the memory corruption happens in the heap:
typedef struct gif_animation { // gif_animation is allocated from heap.
...
// OBS developer decides to move these variables from .bss to heap.
/* General LZW values. They are NO LONGER shared for all GIFs being decoded BECAUSE
THAT IS A TERRIBLE IDEA TO SAVE 10Kb or so per GIF.
*/
unsigned char buf[4];
unsigned char *direct;
int table[2][(1 << GIF_MAX_LZW)];
unsigned char stack[(1 << GIF_MAX_LZW) * 2];
unsigned char *stack_pointer; // Originally points to stack, but a malicious LZW compressed bytestream may cause a linear write OOB.
int code_size, set_code_size;
int max_code, max_code_size;
int clear_code, end_code;
int curbit, lastbit, last_byte;
int firstcode, oldcode;
bool zero_data_block;
bool get_done;
Recommended fix: Apply the libnsgif fix commit to libobs: https://source.netsurf-browser.org/libnsgif.git/commit/?id=a268d2c15252ac58c19f1b19771822c66bcf73b2
OBS provided the follow fix: obsproject/obs-studio@02c1742
Timeline
Date reported: 05/01/2024
Date fixed: 07/18/2024
Date disclosed: 07/30/2024
Summary
OBS (Open Broadcaster Software) is a well-known open source and cross platform software for screen recording and streaming. Unfortunately, a crafted GIF file with malicious LZW compressed data may trigger a heap overflow bug in the OBS image parser library after commit 13890a46e6efc14a64ab5ee4f539d3a8607837a0 in Jan 2016.
Severity
High - an attacker could exploit this to write data beyond the allocated boundaries of memory on the heap.
Proof of Concept
The OBS heap overflow bug recorded by OBS: video
When applying the image source with the malicious GIF file in Ubuntu, OBS will crash immediately. Core dump reports libc tcache heap corruption:
Further Analysis
By using LD_PRELOAD=/usr/aarch64-linux-gnu/lib/libasan.so.6.0.0 obs command, it appears that the heap overflow happens in libobs module:
The corruption happens in gif_next_LZW (libobs/graphics/libnsgif/libnsgif.c), and the libnsgif is an open source project by NetSurf Browser (https://www.netsurf-browser.org/projects/libnsgif/). A further investigation shows that the OBS project ported libnsgif code in Jan 2016 but no one patches known security issues later on. As a result, the OBS is subject to CVE-2015-7505 and CVE-2015-7506 (OOB write and read in .bss section).
However, the OBS project also makes some changes to the libnsgif code. Instead of writing out-of-bounds or reading out-of-bounds in the .bss area, now the memory corruption happens in the heap:
Recommended fix: Apply the libnsgif fix commit to libobs: https://source.netsurf-browser.org/libnsgif.git/commit/?id=a268d2c15252ac58c19f1b19771822c66bcf73b2
OBS provided the follow fix: obsproject/obs-studio@02c1742
Timeline
Date reported: 05/01/2024
Date fixed: 07/18/2024
Date disclosed: 07/30/2024