Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <B08B9FA8-E745-4327-B7D5-7A67648D3F58@gmail.com>
Date: Thu, 23 Jun 2016 01:47:21 +0100
From: Ibrahim el-sayed <i.elsayed92@...il.com>
To: oss-security@...ts.openwall.com
Cc: cve-assign@...re.org
Subject: Fwd: out-of-bounds read in MagickCore/property.c:1396 could lead to memory leak/ Integer overflow read to RCE

Hi Mitre CVE assignment team,
I have submitted the following two bugs to ImageMagick. Both got acknowledged and fixed in the following patch
https://github.com/ImageMagick/ImageMagick/commit/d8ab7f046587f2e9f734b687ba7e6e10147c294b <https://github.com/ImageMagick/ImageMagick/commit/d8ab7f046587f2e9f734b687ba7e6e10147c294b>
I would be so glad if you can issue me CVEs for them

Regards
Ibrahim



> Begin forwarded message:
> 
> From: Ibrahim el-sayed <i.elsayed92@...il.com>
> Subject: Integer overflow that lead to RCE
> Date: June 21, 2016 at 6:58:20 PM GMT+1
> To: security@...gemagick.org
> 
> Hi ImageMagick security team,
> I was fuzzing imagemagick with AFL and I think I found an integer overflow that might lead to remote code execution.
> 
> The vulnerability exists in the following line
> https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/profile.c#L2025 <https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/profile.c#L2025>
> 
> components=(ssize_t) ReadProfileLong(endian,q+4);   << I think component should be size_t
> number_bytes=(size_t) components*format_bytes[format];
> I think components variable is upgraded to integer in this line.
> component is stored in edx in the assembly and before the multplication the following instructions are executed
> 
> 0000000000475D3E movsxd  rax, edx ;edx contains components variable and it is using movsx (move signed extended which I think the main cause of the vulnerability). if The value of components anything above 0xC0000000 the sign extension will be 1 and rax will be 0xFFFFFFFFC0000000. The main problem of this I think because ssize_t which covers the -1 value
> 0000000000475D41 movsxd  rcx, ds:SyncExifProfile_format_bytes[rcx*4]
> 0000000000475D49 imul    rcx, rax
> 0000000000475D4D cmp     rcx, rax ;This is unsigned comparison because of jump below (jl)
> 0000000000475D50 jl      exit
> 
> After the multiplication rcx contains number_bytes as (integer 64bit) and not size_t
> 
> https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/profile.c#L2028 <https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/profile.c#L2028>
> In the if condition, the PoC takes the else part.
> 
> @ line https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/profile.c#L2036 <https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/profile.c#L2036>
> 
> 2036: if ((size_t) (offset+number_bytes) > length)
> An integer oveflow occurs in this comparison because number_bytes is a very large number like (0xFFFFFFFFFFFFFF87) and when we add offset to it which we control we can overflow and the result is < length so we pass this if condition.
> 
> 2040: p=(unsigned char *) (exif+offset);
> At 2040 the offset value is the value we are controlling and can range between 0x7B-0x40000001 as illustrated in the PoC
> 
> pointer p is used later in to write data to it.
> The PoC goes into the switch statement and then choose case 0x011b. And then it write 4 bytes on line
> 2052: (void) WriteProfileLong(endian,(size_t) (image->resolution.y+0.5),p);
> Needless to day we can control image->resolution.y
> Also if we took another path in the switch statement we can also control
> image->orientation or image->units which are the values written to the pointer we can control.
> 
> 
> You can find attached two Proof of Concept files.
> PoC1:
> This PoC will set number_bytes = 0xFFFFFF87  ==>> will be sign extended to 0xFFFFFFFFFFFFFFFF87 and offset = 0x7B.
> This PoC will basically write 4 null bytes into position exif+0x7B (offset)
> 
> PoC2:
> This PoC will set number_bytes = 0xC0000000 which will be sign extended to 0xFFFFFFFFC0000000 and offset = 0x40000001
> This will write 4 null bytes in position exif+0x40000001 (offset).
> 
> PoC2 will cause a seg-fault because usually this memory address (exif+0x40000001) might not be mapped or doesn't have the correct permission to write to
> 
> 
> Regards
> Ibrahim M. El-Sayed
> Security Engineer
> Website: https://www.ibrahim-elsayed.com <https://www.ibrahim-elsayed.com/>
> @ibrahim_mosaad
> 





> Begin forwarded message:
> 
> From: Ibrahim el-sayed <i.elsayed92@...il.com>
> Subject: out-of-bounds read in MagickCore/property.c:1396 could lead to memory leak
> Date: June 21, 2016 at 3:04:23 PM GMT+1
> To: security@...gemagick.org
> 
> Hi ImageMagick Security Team,
> 
> I think I have found a security bug. The bug was found while fuzzing ImageMagick with afl-fuzz
> 
> command: magick identify PoC.jpg
> The vulnerability could lead to information leakage because the pointer is used later to read data from the memory
> 
> 
> MagickCore/property.c:1401 format=(size_t) ReadPropertyUnsignedShort(endian,q+2);
> MagickCore/property.c:1404 components=(ssize_t) ReadPropertySignedLong(endian,q+4);
> 
> The code basically reads the number of entries inside directory object in an image
> MagickCore/property.c:1382 number_entries=(size_t) ReadPropertyUnsignedShort(endian,directory);
> 
> By manipulating bytes at position 0x76 and 0x77 in the PoC image, we can control number_entries variable which is used to in the loop. By controlling number_entries we can partially control q
> MagickCore/property.c:1396 q=(unsigned char *) (directory+(12*entry)+2);
> 
> In the previous line we control the value of "entry". As a result, we can partially control q which can be used later to read arbitrary data from the process of ImageMagick.
> 
> PoC image: https://www.ibrahim-elsayed.com/uploads/PoC_imagemagick_1.jpg <https://www.ibrahim-elsayed.com/uploads/PoC_imagemagick_1.jpg>
> [backtrace]
> storm@...rm ~/f/f/f/crashes> gdb -q magick core.magick.14585
> Reading symbols from magick...done.
> [New LWP 14585]
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
> Core was generated by `magick identify PoC.jpg'.
> Program terminated with signal SIGABRT, Aborted.
> #0 0x00007f110bac6c37 in __GI_raise (sig=sig@...ry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
> 56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
> (gdb) bt
> #0 0x00007f110bac6c37 in __GI_raise (sig=sig@...ry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
> #1 0x00007f110baca028 in __GI_abort () at abort.c:89
> #2 0x0000000000421b5b in MagickSignalHandler (signal_number=6) at MagickCore/magick.c:1310
> #3 <signal handler called>
> #4 0x00007f110bac6c37 in __GI_raise (sig=sig@...ry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
> #5 0x00007f110baca028 in __GI_abort () at abort.c:89
> #6 0x0000000000421b5b in MagickSignalHandler (signal_number=11) at MagickCore/magick.c:1310
> #7 <signal handler called>
> #8 ReadPropertySignedLong (buffer=0x293c000 <error: Cannot access memory at address 0x293c000>,
>     endian=LSBEndian) at MagickCore/property.c:745
> #9 GetEXIFProperty (image=image@...ry=0x291aff0, property=property@...ry=0x7ffe5d180910 "exif:*",
>     exception=exception@...ry=0x28e7f10) at MagickCore/property.c:1404
> #10 0x000000000043e4d8 in GetImageProperty (image=image@...ry=0x291aff0,
>     property=property@...ry=0x7ffe5d180910 "exif:*", exception=exception@...ry=0x28e7f10)
>     at MagickCore/property.c:2197
> #11 0x0000000000441d03 in SetImageProfileInternal (image=image@...ry=0x291aff0,
>     name=name@...ry=0x7ffe5d181990 "exif", profile=profile@...ry=0x28ffe30,
>     recursive=recursive@...ry=MagickFalse, exception=exception@...ry=0x28e7f10) at MagickCore/profile.c:1671
> #12 0x000000000044297a in SetImageProfile (image=image@...ry=0x291aff0, name=name@...ry=0x7ffe5d181990 "exif",
>     profile=profile@...ry=0x28ffe30, exception=exception@...ry=0x28e7f10) at MagickCore/profile.c:1678
> #13 0x000000000053c922 in ReadProfile (jpeg_info=<optimised out>) at coders/jpeg.c:738
> #14 0x00007f1110464975 in ?? () from /usr/lib/x86_64-linux-gnu/libjpeg.so.8
> #15 0x00007f11104629ca in ?? () from /usr/lib/x86_64-linux-gnu/libjpeg.so.8
> #16 0x00007f111045cf57 in jpeg_consume_input () from /usr/lib/x86_64-linux-gnu/libjpeg.so.8
> #17 0x00007f111045d223 in jpeg_read_header () from /usr/lib/x86_64-linux-gnu/libjpeg.so.8
> #18 0x000000000053d669 in ReadJPEGImage (image_info=0x28fa130, exception=0x28e7f10) at coders/jpeg.c:1101
> #19 0x00000000005a06ee in ReadImage (image_info=image_info@...ry=0x28f4b90,
>     exception=exception@...ry=0x28e7f10) at MagickCore/constitute.c:554
> #20 0x0000000000677326 in ReadStream (image_info=image_info@...ry=0x28f1910,
>     stream=stream@...ry=0x59ffb0 <PingStream>, exception=exception@...ry=0x28e7f10) at MagickCore/stream.c:1012
> #21 0x00000000005a0261 in PingImage (image_info=image_info@...ry=0x28ee4f0,
> ---Type <return> to continue, or q <return> to quit---
>     exception=exception@...ry=0x28e7f10) at MagickCore/constitute.c:226
> #22 0x00000000005a04ab in PingImages (image_info=image_info@...ry=0x28ee4f0,
>     filename=filename@...ry=0x28e7f50 "PoC.jpg", exception=exception@...ry=0x28e7f10)
>     at MagickCore/constitute.c:326
> #23 0x00000000006f2741 in IdentifyImageCommand (image_info=0x28eb2c0, image_info@...ry=0x28e8090,
>     argc=argc@...ry=2, argv=0x28e6490, argv@...ry=0x7ffe5d18e4b0, metadata=metadata@...ry=0x7ffe5d18c150,
>     exception=exception@...ry=0x28e7f10) at MagickWand/identify.c:319
> #24 0x000000000071a274 in MagickCommandGenesis (image_info=image_info@...ry=0x28e8090,
>     command=command@...ry=0x6f2180 <IdentifyImageCommand>, argc=2, argv=argv@...ry=0x7ffe5d18e4b0,
>     metadata=0x7ffe5d18d208, exception=exception@...ry=0x28e7f10) at MagickWand/mogrify.c:183
> #25 0x0000000000411f11 in MagickMain (argc=2, argv=0x7ffe5d18e4b0) at utilities/magick.c:250
> #26 0x00007f110bab1f45 in __libc_start_main (main=0x40ec10 <main>, argc=3, argv=0x7ffe5d18e4a8,
>     init=<optimised out>, fini=<optimised out>, rtld_fini=<optimised out>, stack_end=0x7ffe5d18e498)
>     at libc-start.c:287
> #27 0x0000000000411af5 in _start ()
> 


Content of type "text/html" skipped

Download attachment "signature.asc" of type "application/pgp-signature" (843 bytes)

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.