Lucene search

K
huntrHan0nlyAD3C9C4C-76E7-40C8-BD4A-C095ACD8BB40
HistoryApr 04, 2022 - 8:33 a.m.

Improper Validation of Array Index

2022-04-0408:33:04
han0nly
www.huntr.dev
23
vulnerability
array index
heap overflow
master branch
8317a34b7e4ab731e230dcdd81adc9323c5b518b
april 03 2022
radare2
poc
address sanitizer

EPSS

0.001

Percentile

31.9%

This vulnerability is of type Improper Validation of Array Index. The bug exists in latest stable release (radare2-5.6.6) and lastest master branch (8317a34b7e4ab731e230dcdd81adc9323c5b518b, updated in April 03, 2022). Specifically, the vulnerable code (located at libr/bin/format/ne/ne.c) and the bug’s basic explanation are highlighted as follows:

85                      RBinSection *bs = R_NEW0 (RBinSection);
// i is not well validated.
86                      NE_image_segment_entry *se = &bin->segment_entries[i];
87                      if (!bs) {
88                              return segments;
89                      }
// seed1 can trigger this heap overflow.
90                      bs->size = se->length;
91                      bs->vsize = se->minAllocSz ? se->minAllocSz : 64000;
92                      bs->bits = R_SYS_BITS_16;
93                      bs->is_data = se->flags & IS_DATA;
94                      bs->perm = __translate_perms (se->flags);
487                                     char *name;
488                                     if (rel.index > bin->ne_header->ModRefs) {
489                                             name = r_str_newf ("UnknownModule%d_%x", rel.index, off); // ????
490                                     } else {
491                                             printf("modref addr: %X, bin addr: %X, bin->ne_header addr: %X \n",modref,bin,&(bin->ne_header));
// Seed2 can trigger this heap overflow. The rel.index is not validated and can be zero.
492                                             offset = modref[rel.index - 1] + bin->header_offset + bin->ne_header->ImportNameTable;
493                                             name = __read_nonnull_str_at (bin->buf, offset);
494                                     }
495                                     if (rel.flags & IMPORTED_ORD) {
496                                             imp->ordinal = rel.func_ord;

Proof of Concept

Build the radare2 (8317a34b7e4ab731e230dcdd81adc9323c5b518b, updated in April 03, 2022) and run it using the input POC.

# build the radare2 with address sanitizer
export CFLAGS=" -fsanitize=address "; export CXXFLAGS=" -fsanitize=address "; export LDFLAGS=" -fsanitize=address ";
CFGARG=" --enable-shared=no " PREFIX=`realpath install` bash sys/build.sh
# disable some features of address sanitizer to avoid false positives
export ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=0:allocator_may_return_null=1:detect_odr_violation=0
# trigger the crash
./radare2 -A -q POC_FILE

The crash stack is:

# seed1
=================================================================
==28776==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62f00000deda at pc 0x7ffff2a83101 bp 0x7fffffffd820 sp 0x7fffffffd818
READ of size 2 at 0x62f00000deda thread T0
    #0 0x7ffff2a83100  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x619100)
    #1 0x7ffff2a84696  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x61a696)
    #2 0x7ffff264667f  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1dc67f)
    #3 0x7ffff2645004  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1db004)
    #4 0x7ffff262a1fe  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1c01fe)
    #5 0x7ffff25cd9fb  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1639fb)
    #6 0x7ffff25ccad6  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x162ad6)
    #7 0x7ffff384136c  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_core.so+0x6b236c)
    #8 0x7ffff7548697  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_main.so+0x99697)
    #9 0x7ffff72bc0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #10 0x55555557239d  (/src/cmdline-fuzz/exprs/radare2-5.5.4/radare2+0x1e39d)

0x62f00000deda is located 2 bytes to the right of 56024-byte region [0x62f000000400,0x62f00000ded8)
allocated by thread T0 here:
    #0 0x5555555ed772  (/src/cmdline-fuzz/exprs/radare2-5.5.4/radare2+0x99772)
    #1 0x7ffff2a895dd  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x61f5dd)
    #2 0x7ffff2a8b3fb  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x6213fb)
    #3 0x7ffff262a1fe  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1c01fe)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x619100)
Shadow bytes around the buggy address:
  0x0c5e7fff9b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c5e7fff9b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c5e7fff9ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c5e7fff9bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c5e7fff9bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c5e7fff9bd0: 00 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa
  0x0c5e7fff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9c20: 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Shadow gap:              cc
==28776==ABORTING

Program received signal SIGABRT, Aborted.
0x00007ffff72db18b in raise () from /lib/x86_64-linux-gnu/libc.so.6

(gdb) bt
#0  0x00007ffff72db18b in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff72ba859 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x000055555560ba77 in __sanitizer::Abort() ()
#3  0x0000555555609fa1 in __sanitizer::Die() ()
#4  0x00005555555f14e4 in __asan::ScopedInErrorReport::~ScopedInErrorReport() ()
#5  0x00005555555f30aa in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#6  0x00005555555f3828 in __asan_report_load2 ()
#7  0x00007ffff2a83101 in r_bin_ne_get_segments (bin=<optimized out>) at /src/cmdline-fuzz/exprs/radare2-5.5.4/src/libr/../libr/bin/p/../format/ne/ne.c:90
#8  0x00007ffff2a84697 in r_bin_ne_get_entrypoints (bin=<optimized out>) at /src/cmdline-fuzz/exprs/radare2-5.5.4/src/libr/../libr/bin/p/../format/ne/ne.c:359
#9  0x00007ffff2646680 in r_bin_object_set_items (bf=<optimized out>, bo=<optimized out>) at bobj.c:306
#10 0x00007ffff2645005 in r_bin_object_new (bf=<optimized out>, plugin=<optimized out>, baseaddr=<optimized out>, loadaddr=<optimized out>, offset=<optimized out>, sz=<optimized out>) at bobj.c:168
#11 0x00007ffff262a1ff in r_bin_file_new_from_buffer (bin=0x616000000680, file=<optimized out>, buf=<optimized out>, rawstr=<optimized out>, baseaddr=<optimized out>, loadaddr=<optimized out>, fd=<optimized out>,
    pluginname=<optimized out>) at bfile.c:585
#12 0x00007ffff25cd9fc in r_bin_open_buf (bin=<optimized out>, buf=<optimized out>, opt=<optimized out>) at bin.c:279
#13 0x00007ffff25ccad7 in r_bin_open_io (bin=0x616000000680, opt=<optimized out>) at bin.c:339
#14 0x00007ffff384136d in r_core_file_do_load_for_io_plugin (r=0x7fffec2d3800, baseaddr=18446744073709551615, loadaddr=0) at cfile.c:435
#15 r_core_bin_load (r=0x7fffec2d3800, filenameuri=<optimized out>, baddr=<optimized out>) at cfile.c:636
#16 0x00007ffff7548698 in r_main_radare2 (argc=<optimized out>, argv=<optimized out>) at radare2.c:1188
#17 0x00007ffff72bc0b3 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#18 0x000055555557239e in _start ()
# seed2
=================================================================
==28700==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200006c50e at pc 0x7ffff2a88d19 bp 0x7fffffffd610 sp 0x7fffffffd608
READ of size 2 at 0x60200006c50e thread T0
    #0 0x7ffff2a88d18  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x61ed18)
    #1 0x7ffff26477f9  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1dd7f9)
    #2 0x7ffff2645004  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1db004)
    #3 0x7ffff262a1fe  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1c01fe)
    #4 0x7ffff25cd9fb  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1639fb)
    #5 0x7ffff25ccad6  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x162ad6)
    #6 0x7ffff384136c  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_core.so+0x6b236c)
    #7 0x7ffff7548697  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_main.so+0x99697)
    #8 0x7ffff72bc0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #9 0x55555557239d  (/src/cmdline-fuzz/exprs/radare2-5.5.4/radare2+0x1e39d)

0x60200006c50e is located 2 bytes to the left of 1-byte region [0x60200006c510,0x60200006c511)
allocated by thread T0 here:
    #0 0x5555555ed5fd  (/src/cmdline-fuzz/exprs/radare2-5.5.4/radare2+0x995fd)
    #1 0x7ffff2a86194  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x61c194)
    #2 0x7ffff26477f9  (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x1dd7f9)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/src/cmdline-fuzz/exprs/radare2-5.5.4/src/install/lib/libr_bin.so+0x61ed18)
Shadow bytes around the buggy address:
  0x0c0480005850: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c0480005860: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c0480005870: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c0480005880: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c0480005890: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
=>0x0c04800058a0: fa[fa]01 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800058b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800058c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800058d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800058e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800058f0: 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Shadow gap:              cc
==28700==ABORTING

Program received signal SIGABRT, Aborted.
0x00007ffff72db18b in raise () from /lib/x86_64-linux-gnu/libc.so.6

(gdb) bt
#0  0x00007ffff72db18b in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff72ba859 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x000055555560ba77 in __sanitizer::Abort() ()
#3  0x0000555555609fa1 in __sanitizer::Die() ()
#4  0x00005555555f14e4 in __asan::ScopedInErrorReport::~ScopedInErrorReport() ()
#5  0x00005555555f30aa in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#6  0x00005555555f3828 in __asan_report_load2 ()
#7  0x00007ffff2a88d19 in r_bin_ne_get_relocs (bin=<optimized out>) at /src/cmdline-fuzz/exprs/radare2-5.5.4/src/libr/../libr/bin/p/../format/ne/ne.c:490
#8  0x00007ffff26477fa in r_bin_object_set_items (bf=<optimized out>, bo=<optimized out>) at bobj.c:349
#9  0x00007ffff2645005 in r_bin_object_new (bf=<optimized out>, plugin=<optimized out>, baseaddr=<optimized out>, loadaddr=<optimized out>, offset=<optimized out>, sz=<optimized out>) at bobj.c:168
#10 0x00007ffff262a1ff in r_bin_file_new_from_buffer (bin=0x616000000680, file=<optimized out>, buf=<optimized out>, rawstr=<optimized out>, baseaddr=<optimized out>, loadaddr=<optimized out>, fd=<optimized out>,
    pluginname=<optimized out>) at bfile.c:585
#11 0x00007ffff25cd9fc in r_bin_open_buf (bin=<optimized out>, buf=<optimized out>, opt=<optimized out>) at bin.c:279
#12 0x00007ffff25ccad7 in r_bin_open_io (bin=0x616000000680, opt=<optimized out>) at bin.c:339
#13 0x00007ffff384136d in r_core_file_do_load_for_io_plugin (r=0x7fffec2d3800, baseaddr=18446744073709551615, loadaddr=0) at cfile.c:435
#14 r_core_bin_load (r=0x7fffec2d3800, filenameuri=<optimized out>, baddr=<optimized out>) at cfile.c:636
#15 0x00007ffff7548698 in r_main_radare2 (argc=<optimized out>, argv=<optimized out>) at radare2.c:1188
#16 0x00007ffff72bc0b3 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#17 0x000055555557239e in _start ()

EPSS

0.001

Percentile

31.9%

Related for AD3C9C4C-76E7-40C8-BD4A-C095ACD8BB40