Out-of-bounds Read in bfabiszewski/libmobi

Valid

Reported on

Sep 12th 2021


✍️ Description

Overview

This vulnerability is of out-of-bound read, 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

The root cause is the unsafe way of decompressing user given input in mobi_decompress_huffman_internal (src/compression.c line 118). Specifically, the code_length can be much larger (the value is calculated based on user's input, in our PoC, it has the value 66) than the real size of huffcdic->maxcode_table (is fixed as 33 in src/compression.h). Therefore, attacker can make the program crash (if read to an invalid memory address) or get memory sensitive information (critical object's address) to bypass ASLR.

The following code shows the vulnerable point.

        if (!(t1 & 0x80)) {
            /* get offset from mincode, maxcode tables */
            // Here makes the code_length be much larger than 33 which is the maxcode_table's size
            while (code < huffcdic->mincode_table[code_length]) {
                code_length++;
            }
            // HERE causes the out-of-bound read
            maxcode = huffcdic->maxcode_table[code_length];
        }

Fix Suggestion

A simple fix way is to check whether code_length 's value is greater than 33 in here . Note that this may not be a complete fix since all the similar scenario in all decompress functions should be checked. I'm willing to help you to build a complete patch!

        if (!(t1 & 0x80)) {
            /* get offset from mincode, maxcode tables */
            while (code < huffcdic->mincode_table[code_length]) {
                  code_length++;
            }
            // SIMPLE FIX
            if (code_length >= (sizeof(huffcdic->maxcode_table) / sizeof(huffcdic->maxcode_table[0])) )
                  return MOBI_DATA_CORRUPT;
            maxcode = huffcdic->maxcode_table[code_length];
        }

🕵️‍♂️ 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:

=================================================================
==6829==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61a000001e24 at pc 0x7ffff75863b6 bp 0x7fffffffbae0 sp 0x7fffffffbad0
READ of size 4 at 0x61a000001e24 thread T0
    #0 0x7ffff75863b5 in mobi_decompress_huffman_internal /src/libmobi/libmobi-git/src/compression.c:146
    #1 0x7ffff75868c5 in mobi_decompress_huffman_internal /src/libmobi/libmobi-git/src/compression.c:180
    #2 0x7ffff75868c5 in mobi_decompress_huffman_internal /src/libmobi/libmobi-git/src/compression.c:180
    #3 0x7ffff75868c5 in mobi_decompress_huffman_internal /src/libmobi/libmobi-git/src/compression.c:180
    #4 0x7ffff7586a1e in mobi_decompress_huffman /src/libmobi/libmobi-git/src/compression.c:213
    #5 0x7ffff75ad1eb in mobi_decompress_content /src/libmobi/libmobi-git/src/util.c:1782
    #6 0x7ffff75ad677 in mobi_dump_rawml /src/libmobi/libmobi-git/src/util.c:1856
    #7 0x5555555630e4 in dump_rawml /src/libmobi/libmobi-git/tools/mobitool.c:333
    #8 0x5555555661e3 in loadfilename /src/libmobi/libmobi-git/tools/mobitool.c:775
    #9 0x555555566e46 in main /src/libmobi/libmobi-git/tools/mobitool.c:962
    #10 0x7ffff73a90b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #11 0x55555555dead in _start (/src/libmobi/libmobi-git/install/bin/mobitool+0x9ead)

Address 0x61a000001e24 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/libmobi/libmobi-git/src/compression.c:146 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)). Likely, 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 submitted a
3 months ago
Ziding Zhang
3 months 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 3 months ago
Bartek Fabiszewski validated this vulnerability 3 months 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 bec783 3 months ago
Cen Zhang has been awarded the fix bounty
Cen Zhang
2 months ago

Researcher


@admin, may you help me for applying cve of these three libmobi vulnerability reports? Thanks!

Jamie Slome
2 months ago

Admin


Can you please e-mail security@huntr.dev with the three report URLs and we can begin arranging this for you.

Cen Zhang
2 months ago

Researcher


Noted, thanks!

Jamie Slome
2 months 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
2 months ago

Maintainer


Yes, thanks!