I am running some experiments for AFLAPI and it has found a heap-buffer-overflow in xlnt::detail::izstream::read_central_header. It seems to be hard to be exploited, but this bug also allows attackers to lead to Dos, so I report it here.
To reproduce:
• Complie the hole project with ASAN
• Complie the harness with ASAN: g++-6 -fsanitize=address -o harness harness.cc -lxlnt
• Run harness: ./harness ./buf_overflow_testcase
ASAN says:
=================================================================
==2167==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff1 at pc 0x7f0d5da13f5d bp 0x7ffe488d2b80 sp 0x7ffe488d2b70
READ of size 1 at 0x60200000eff1 thread T0
0 0x7f0d5da13f5c in xlnt::detail::izstream::read_central_header() (/usr/local/lib/libxlnt.so.1.5.0+0x54cf5c)
#1 0x7f0d5da13a10 in xlnt::detail::izstream::izstream(std::istream&) (/usr/local/lib/libxlnt.so.1.5.0+0x54ca10)
#2 0x7f0d5d96069e in xlnt::detail::xlsx_consumer::read(std::istream&) (/usr/local/lib/libxlnt.so.1.5.0+0x49969e)
#3 0x7f0d5d845e2e in xlnt::workbook::load(std::istream&) (/usr/local/lib/libxlnt.so.1.5.0+0x37ee2e)
#4 0x7f0d5d846719 in xlnt::workbook::load(xlnt::path const&) (/usr/local/lib/libxlnt.so.1.5.0+0x37f719)
#5 0x7f0d5d8464fe in xlnt::workbook::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/usr/local/lib/libxlnt.so.1.5.0+0x37f4fe)
#6 0x55864e4f23d7 in main (/home/ubuntu/xlnt/Fuzz/harness+0x23d7)
#7 0x7f0d5d0fc082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
#8 0x55864e4f219d in _start (/home/ubuntu/xlnt/Fuzz/harness+0x219d)
0x60200000eff1 is located 0 bytes to the right of 1-byte region [0x60200000eff0,0x60200000eff1)
allocated by thread T0 here:
0 0x7f0d5dc85ec0 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.3+0xc7ec0)
#1 0x7f0d5d89d9e6 in __gnu_cxx::new_allocator<unsigned char>::allocate(unsigned long, void const*) (/usr/local/lib/libxlnt.so.1.5.0+0x3d69e6)
#2 0x7f0d5d895c3d in std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned long) (/usr/local/lib/libxlnt.so.1.5.0+0x3cec3d)
#3 0x7f0d5d88a4d9 in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_allocate(unsigned long) (/usr/local/lib/libxlnt.so.1.5.0+0x3c34d9)
#4 0x7f0d5d8ed440 in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_create_storage(unsigned long) (/usr/local/lib/libxlnt.so.1.5.0+0x426440)
#5 0x7f0d5d8ed294 in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_Vector_base(unsigned long, std::allocator<unsigned char> const&) (/usr/local/lib/libxlnt.so.1.5.0+0x426294)
#6 0x7f0d5d901149 in std::vector<unsigned char, std::allocator<unsigned char> >::vector(unsigned long, unsigned char const&, std::allocator<unsigned char> const&) (/usr/local/lib/libxlnt.so.1.5.0+0x43a149)
#7 0x7f0d5da13dbd in xlnt::detail::izstream::read_central_header() (/usr/local/lib/libxlnt.so.1.5.0+0x54cdbd)
#8 0x7f0d5da13a10 in xlnt::detail::izstream::izstream(std::istream&) (/usr/local/lib/libxlnt.so.1.5.0+0x54ca10)
#9 0x7f0d5d96069e in xlnt::detail::xlsx_consumer::read(std::istream&) (/usr/local/lib/libxlnt.so.1.5.0+0x49969e)
#10 0x7f0d5d845e2e in xlnt::workbook::load(std::istream&) (/usr/local/lib/libxlnt.so.1.5.0+0x37ee2e)
#11 0x7f0d5d846719 in xlnt::workbook::load(xlnt::path const&) (/usr/local/lib/libxlnt.so.1.5.0+0x37f719)
#12 0x7f0d5d8464fe in xlnt::workbook::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/usr/local/lib/libxlnt.so.1.5.0+0x37f4fe)
#13 0x55864e4f23d7 in main (/home/ubuntu/xlnt/Fuzz/harness+0x23d7)
#14 0x7f0d5d0fc082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/lib/libxlnt.so.1.5.0+0x54cf5c) in xlnt::detail::izstream::read_central_header()
Shadow bytes around the buggy address:
0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[01]fa
0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e40: 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
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
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
==2167==ABORTING
Impact: An attacker can exploit this vulnerability by submitting a malicious xlsx file that exploits this bug which will result in a DoS even buffer overflow.
Hi,
I am running some experiments for AFLAPI and it has found a heap-buffer-overflow in xlnt::detail::izstream::read_central_header. It seems to be hard to be exploited, but this bug also allows attackers to lead to Dos, so I report it here.
Environment: Ubuntu 20.04 + g++ 6.0
Harness code:
Poc here: buf_overflow_testcase.zip
To reproduce: • Complie the hole project with ASAN • Complie the harness with ASAN:
g++-6 -fsanitize=address -o harness harness.cc -lxlnt
• Run harness:./harness ./buf_overflow_testcase
ASAN says:
================================================================= ==2167==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff1 at pc 0x7f0d5da13f5d bp 0x7ffe488d2b80 sp 0x7ffe488d2b70 READ of size 1 at 0x60200000eff1 thread T0
0 0x7f0d5da13f5c in xlnt::detail::izstream::read_central_header() (/usr/local/lib/libxlnt.so.1.5.0+0x54cf5c)
0x60200000eff1 is located 0 bytes to the right of 1-byte region [0x60200000eff0,0x60200000eff1) allocated by thread T0 here:
0 0x7f0d5dc85ec0 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.3+0xc7ec0)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/lib/libxlnt.so.1.5.0+0x54cf5c) in xlnt::detail::izstream::read_central_header() Shadow bytes around the buggy address: 0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c047fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[01]fa 0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e40: 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 Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 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 ==2167==ABORTING
Impact: An attacker can exploit this vulnerability by submitting a malicious xlsx file that exploits this bug which will result in a DoS even buffer overflow.