AgentD / squashfs-tools-ng

A new set of tools and libraries for working with SquashFS images
Other
196 stars 30 forks source link

Heap Buffer Overflow found by fuzzing #13

Closed Dr-Emann closed 5 years ago

Dr-Emann commented 5 years ago

Base 64 encoded squashfs archive:

aHNxcwcAAAAAABBdABAAABwAAAABAAwAqAECAAQAAAAgAAAAAAAAAAIBAAAAAAAA+gAAAAAAAAD/
/////////2MAAAAAAAAApQAAAAAAAADOAAAAAAAAAOgAAAAAAAAAemkKQIADALQBAAABANQMXl0A
9AAAAAAAAP7///8AAAAAAwAAAAEA/QEAAAEA1AxeXQIAAAAAAAAAFQAgGTgVAAADAAAAFYAAAAAA
AAAAAAEAAAAAAAAAAgAAAP9/AAAAAAAAAAAAAwAAAQAAAAC8AAAAAAAAABCAAAAAAAAAAOwRAAAA
AAAAANYAAAAAAAAACIDpAwAA6wMAAPAAAAAAAAAA

Compiled master with ASAN enabled for AFL, using 32bit

Running rdsquashfs -d bad.squashfs outputs the following from ASAN:


=================================================================
==23158==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf4f016e0 at pc 0x081085bb bp 0xffe0ed28 sp 0xffe0e900
WRITE of size 8168 at 0xf4f016e0 thread T0
    #0 0x81085ba in __asan_memcpy (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba)
    #1 0x814ff9a in meta_reader_read /home/dremann/Development/squashfs-tools-ng/lib/sqfs/meta_reader.c:143:3
    #2 0x8155860 in read_inode_slink /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:178:6
    #3 0x8155860 in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:236
    #4 0x81518f4 in fill_dir /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:125:12
    #5 0x8150a07 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:279:6
    #6 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
    #7 0x813a4fa in main /home/dremann/Development/squashfs-tools-ng/unpack/rdsquashfs.c:33:6
    #8 0xf7c11750 in __libc_start_main (/lib32/libc.so.6+0x1e750)
    #9 0x8062561 in _start (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8062561)

0xf4f016e0 is located 1 bytes to the right of 63-byte region [0xf4f016a0,0xf4f016df)
allocated by thread T0 here:
    #0 0x8109575 in calloc (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8109575)
    #1 0x81556bc in read_inode_slink /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:168:8
    #2 0x81556bc in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:236
    #3 0x81518f4 in fill_dir /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:125:12
    #4 0x8150a07 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:279:6
    #5 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba) in __asan_memcpy
Shadow bytes around the buggy address:
  0x3e9e0280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e0290: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e02a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e02b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e02c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3e9e02d0: fa fa fa fa 00 00 00 00 00 00 00 07[fa]fa fa fa
  0x3e9e02e0: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x3e9e02f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e0300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e0310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e9e0320: 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
==23158==ABORTING
Dr-Emann commented 5 years ago

Possibly related crash: Base64'd archive:

aHNxcwEAAADZhl5dABAAAAAAAAABAAwAywECAAQAAAAAAAAAAAAAAKYAAAAAAAAAngAAAAAAAAD/
/////////2AAAAAAAAAAggAAAAAAAACCAAAAAAAAAIwAAAAAAAAAIIAJAP0BAAABALKGXl0BAAAA
AAAAAAIAAAADAP////8AAAiAAAAAAAAAAACCAAAAAAAAAAiA6QMAAOsDAACUAAAAAAAAAA==

ASAN:

=================================================================
==2198==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5300771 at pc 0x081085bb bp 0xff8b3308 sp 0xff8b2ee0
WRITE of size 16 at 0xf5300771 thread T0
    #0 0x81085ba in __asan_memcpy (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba)
    #1 0x8155c48 in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:141:14
    #2 0x8155c48 in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
    #3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
    #4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
    #5 0x813a4fa in main /home/dremann/Development/squashfs-tools-ng/unpack/rdsquashfs.c:33:6
    #6 0xf7c3b750 in __libc_start_main (/lib32/libc.so.6+0x1e750)
    #7 0x8062561 in _start (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8062561)

0xf5300771 is located 0 bytes to the right of 1-byte region [0xf5300770,0xf5300771)
allocated by thread T0 here:
    #0 0x8109575 in calloc (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8109575)
    #1 0x8155bfc in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:135:8
    #2 0x8155bfc in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
    #3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
    #4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba) in __asan_memcpy
Shadow bytes around the buggy address:
  0x3ea60090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea600e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[01]fa
  0x3ea600f0: fa fa fd fa fa fa 00 fa fa fa fa fa fa fa fa fa
  0x3ea60100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea60110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea60120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea60130: 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
==2198==ABORTING
Dr-Emann commented 5 years ago

Another possible one that looks about the same:

Base64 archive:

aHNxcwEAAADZhl5dABAAAAAAAAABAAwAywECAAQAAAAAAAAAAAAAAKYAAAAAAAAAngAAAAAAAAD/
/////////2AAAAAAAAAAggAAAAAAAACCAAAAAAAAAIwAAAAAAAAAIIAJAP0BAAABALKCAAAAAAAA
AIwAAAAAAAAAIP////8BAAABALKGXl0AEAAAAAAAAAAAAAiA6QMAAOsDAACUAAAAAAAAAA==

ASAN:

=================================================================
==21581==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5300778 at pc 0x081085bb bp 0xffbe7da8 sp 0xffbe7980
WRITE of size 16 at 0xf5300778 thread T0
    #0 0x81085ba in __asan_memcpy (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba)
    #1 0x8155c48 in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:141:14
    #2 0x8155c48 in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
    #3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
    #4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
    #5 0x813a4fa in main /home/dremann/Development/squashfs-tools-ng/unpack/rdsquashfs.c:33:6
    #6 0xf7bfc750 in __libc_start_main (/lib32/libc.so.6+0x1e750)
    #7 0x8062561 in _start (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8062561)

0xf5300778 is located 0 bytes to the right of 8-byte region [0xf5300770,0xf5300778)
allocated by thread T0 here:
    #0 0x8109575 in calloc (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8109575)
    #1 0x8155bfc in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:135:8
    #2 0x8155bfc in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
    #3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
    #4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba) in __asan_memcpy
Shadow bytes around the buggy address:
  0x3ea60090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea600d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea600e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00[fa]
  0x3ea600f0: fa fa fd fa fa fa 00 fa fa fa fa fa fa fa fa fa
  0x3ea60100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea60110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea60120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea60130: 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
==21581==ABORTING
AgentD commented 5 years ago

Again, thanks for all the effort!

The issue here turns out to be unsigned integer overflows. The code turns a lot of on-disk data structures into structs with flexible array members and contains the pattern type *x = calloc(1, sizeof(*x) + foo); all over the place, where foo is read from disk and thus attacker controlled.

If foo happens to be the same size as size_t, this can easily produce an overflow with (in some cases) the total sum being less than the size of even the base struct.

I guess #14 is also related, but I haven't looked at it in more detail yet.

I already pushed a few commits that fix a few places that could be found with a simple grep and where straight forward to replace. I'm still busy replacing the not so straight forward cases and more thoroughly reviewing all code that does size accounting.

Dr-Emann commented 5 years ago

Things are looking pretty good: coming up on 24 hours fuzzing with no crashes under AFL, compiled with ASAN, using commit fa893f8.