Lucene search

K
huntrOcciaEFB3E261-3F7D-4A45-8114-E0ACE6B21516
HistorySep 12, 2021 - 3:25 a.m.

in bfabiszewski/libmobi

2021-09-1203:25:14
occia
www.huntr.dev
5

0.002 Low

EPSS

Percentile

54.8%

✍️ 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->mincode_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 mincode_table's size
            while (code < huffcdic->mincode_table[code_length]) {
                code_length++;
            }
            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]) {
                // OLD CODE:
                // code_length++;
                // SIMPLE FIX, MAY NOT BE COMPLETE:
                code_length++;
                if (code_length >= (sizeof(huffcdic->mincode_table) / sizeof(huffcdic->mincode_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:

=================================================================
==8324==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61a000001db0 at pc 0x7ffff758633b bp 0x7fffffffbae0 sp 0x7fffffffbad0
READ of size 4 at 0x61a000001db0 thread T0
    #0 0x7ffff758633a in mobi_decompress_huffman_internal /src/libmobi/libmobi-git/src/compression.c:143
    #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)

0x61a000001db0 is located 0 bytes to the right of 1328-byte region [0x61a000001880,0x61a000001db0)
allocated by thread T0 here:
    #0 0x7ffff769f6e7 in calloc (/lib/x86_64-linux-gnu/libasan.so.6+0xb06e7)
    #1 0x7ffff758ee67 in mobi_init_huffcdic /src/libmobi/libmobi-git/src/memory.c:195
    #2 0x7ffff75aca61 in mobi_decompress_content /src/libmobi/libmobi-git/src/util.c:1679
    #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:143 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.

0.002 Low

EPSS

Percentile

54.8%

Related for EFB3E261-3F7D-4A45-8114-E0ACE6B21516