Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
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 ]

[ CONTENT OF TYPE application/pgp-signature SKIPPED ]

Powered by blists - more mailing lists

Your e-mail address:

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

Powered by Openwall GNU/*/Linux - Powered by OpenVZ