Use of Out-of-range Pointer Offset in bfabiszewski/libmobi

Valid

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.

Cen Zhang
a year ago

Researcher


The related issue I posted is at here

Z-Old
a year ago

Admin


Hey Cen, I've emailed the maintainer for you.

We have contacted a member of the bfabiszewski/libmobi team and are waiting to hear back a year ago
Cen Zhang
a year ago

Researcher


noted, thanks for the emails of all related reports!

Bartek Fabiszewski validated this vulnerability a year ago
Cen Zhang has been awarded the disclosure bounty
The fix bounty is now up for grabs
Bartek Fabiszewski confirmed that a fix has been merged on c78e18 a year ago
Bartek Fabiszewski has been awarded the fix bounty
Jamie Slome
a year ago

Admin


@bartek - the researcher has requested a CVE for this report. Before we proceed, are you happy to publish a CVE for this report?

Bartek
a year ago

Maintainer


Yes, thanks!

Jamie Slome
a year ago

Admin


CVE published! 🎊

Cen Zhang
a year ago

Researcher


many thanks~

to join this conversation