Use of Out-of-range Pointer Offset in bfabiszewski/libmobi
Reported on
Sep 12th 2021
โ๏ธ Description
Overview
This vulnerability is the use of out-of-range pointer offset, which lets attackers read memory information beyond the buffer size. Possibly, attackers can use this to do DOS (Denial of Service) attack or ALSR bypass (by reading sensitive memory address information) to all applications which use the LibMobi library.
Root Cause
As shown in the following code, there is no size information stored when creates huffcdic->symbols
, and consequently, the pointer offset cannot be checked when use that buffer (huffcdic->symbols[cdic->index]
). By crafting the input mobi file, attackers can let program reads invalid memory (causes DOS) or possibly dump the critical memory address information (used to bypass ASLR).
// code where allocates the huffcdic->symbol_offsets, src/read.c L736-L740
// here it doesn't store the length of huffcdic->symbols
huffcdic->symbols = malloc((huff_rec_count - 1) * sizeof(*huffcdic->symbols));
if (huffcdic->symbols == NULL) {
debug_print("%s\n", "Memory allocation failed");
return MOBI_MALLOC_FAILED;
}
// code where triggers the oob read, src/compression.c L156-L163
// here it doesn't check cdic_index < length of huffcdic->symbols
uint16_t cdic_index = (uint16_t) ((uint32_t)index >> huffcdic->code_length);
if (index >= huffcdic->index_count) {
debug_print("Wrong symbol offsets index: %u\n", index);
return MOBI_DATA_CORRUPT;
}
/* get offset */
uint32_t offset = huffcdic->symbol_offsets[index];
uint32_t symbol_length = (uint32_t) huffcdic->symbols[cdic_index][offset] << 8 | (uint32_t) huffcdic->symbols[cdic_index][offset + 1];
Fix Suggestion
I think a reasonable patch for this vulnerability requires your developers' help. At first, I thought the simple fix way is to add a member to protect huffcdic->symbols
as it did for huffcdic->symbol_offsets
. However, I found that the huffcdic->symbols[xxx]
is also not protected. Then I stopped here since fixing all things related requires too many code changes. Feel free to contact me if you need my help when fixing this!
๐ต๏ธโโ๏ธ Proof of Concept
- Download latest
libmobi
and compile it with Address Sanitizer:CFLAGS=" -fsanitize=address " CXXFLAGS=" -fsanitize=address "
- Use the following command and this POC-FILE to reproduce the crash:
# enable address sanitizer
export ASAN_OPTIONS=abort_on_error=1:disable_coredump=0:unmap_shadow_on_exit=1
# reproduce the crash
./mobitool -cdeimsrux7 -o any-tmp-dir-path POC-FILE
You should get similar crash information as follows:
=================================================================
==26013==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000001118 at pc 0x7ffff758659d bp 0x7fffffffbdf0 sp 0x7fffffffbde0
READ of size 8 at 0x602000001118 thread T0
#0 0x7ffff758659c in mobi_decompress_huffman_internal /src/libmobi/libmobi-git/src/compression.c:163
#1 0x7ffff7586a1e in mobi_decompress_huffman /src/libmobi/libmobi-git/src/compression.c:213
#2 0x7ffff75ad1eb in mobi_decompress_content /src/libmobi/libmobi-git/src/util.c:1782
#3 0x7ffff75ad677 in mobi_dump_rawml /src/libmobi/libmobi-git/src/util.c:1856
#4 0x5555555630e4 in dump_rawml /src/libmobi/libmobi-git/tools/mobitool.c:333
#5 0x5555555661e3 in loadfilename /src/libmobi/libmobi-git/tools/mobitool.c:775
#6 0x555555566e46 in main /src/libmobi/libmobi-git/tools/mobitool.c:962
#7 0x7ffff73a90b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#8 0x55555555dead in _start (/src/libmobi/libmobi-git/install/bin/mobitool+0x9ead)
0x602000001118 is located 0 bytes to the right of 8-byte region [0x602000001110,0x602000001118)
allocated by thread T0 here:
#0 0x7ffff769f517 in malloc (/lib/x86_64-linux-gnu/libasan.so.6+0xb0517)
#1 0x7ffff75a335b in mobi_parse_huffdic /src/libmobi/libmobi-git/src/read.c:736
#2 0x7ffff75aca96 in mobi_decompress_content /src/libmobi/libmobi-git/src/util.c:1684
#3 0x7ffff75ad677 in mobi_dump_rawml /src/libmobi/libmobi-git/src/util.c:1856
#4 0x5555555630e4 in dump_rawml /src/libmobi/libmobi-git/tools/mobitool.c:333
#5 0x5555555661e3 in loadfilename /src/libmobi/libmobi-git/tools/mobitool.c:775
#6 0x555555566e46 in main /src/libmobi/libmobi-git/tools/mobitool.c:962
#7 0x7ffff73a90b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/libmobi/libmobi-git/src/compression.c:163 in mobi_decompress_huffman_internal
๐ฅ Impact
This vulnerability is capable of overwriting memory content with user given values. For all applications using libmobi
(commits c814c4aba4e090fa32805ff8ff459df6c2c61b5c
in Sep 10th, 2021 or release version 0.7 (2020 Sep 10th)), possibly attackers can use this to do DOS (Denial of Service) attack or ALSR bypass (by reading sensitive memory address information) to any application which uses the LibMobi library.
@bartek - the researcher has requested a CVE for this report. Before we proceed, are you happy to publish a CVE for this report?