php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #77270 imagecolormatch Out Of Bounds Write on Heap
Submitted: 2018-12-09 09:28 UTC Modified: 2019-01-27 19:00 UTC
From: sscannell at ripstech dot com Assigned: stas (profile)
Status: Closed Package: GD related
PHP Version: 7.2.13 OS:
Private report: No CVE-ID: 2019-6977
 [2018-12-09 09:28 UTC] sscannell at ripstech dot com
Description:
------------
It is possible to write up to 1200 bytes over the boundaries of a buffer allocated in the imagecolormatch function, which then calls gdImageColorMatch()

The function takes two gdImagePtr as arguments and wants to compare both of them. It then allocates a dynamic buffer with the following calculation:

buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * im2->colorsTotal, 0);

im2->colorsTotal is under the control of an attacker. By simply allocating only one color to the second image, the calculation becomes sizeof(unsigned long) (8 byte on a 64 bit system) * 5 * 1, which results in a buffer of 40 bytes.

The buffer is then written to in a for loop.
	for (x=0; x<im1->sx; x++) {
		for( y=0; y<im1->sy; y++ ) {
			color = im2->pixels[y][x];
			rgb = im1->tpixels[y][x];
			bp = buf + (color * 5);
			(*(bp++))++;
			*(bp++) += gdTrueColorGetRed(rgb);
			*(bp++) += gdTrueColorGetGreen(rgb);
			*(bp++) += gdTrueColorGetBlue(rgb);
			*(bp++) += gdTrueColorGetAlpha(rgb);
		}

The buffer is written to by means of a color being the index:
color = im2->pixels[y][x];
..
bp = buf + (color * 5);

However, an attacker can set the value of color to be at maximum 255 (since it is a char). This would result in bp pointing at buffer + 1275 bytes. Since buffer is only 40 bytes big, this leads to an out of bounds write with data that is also under the control of the attacker.


Test script:
---------------
<?php
$img1 = imagecreatetruecolor(0xfff, 0xfff);
$img2 = imagecreate(0xfff, 0xfff);
imagecolorallocate($img2, 0, 0, 0);
imagesetpixel($img2, 0, 0, 255);
imagecolormatch($img1, $img2);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-12-09 09:34 UTC] stas@php.net
Not sure I understand where is the security issue here (please check out https://wiki.php.net/security).
 [2018-12-09 12:04 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 [2018-12-09 12:04 UTC] cmb@php.net
This would be a security issue, if code like

  $img1 = imagecreatefromjpeg($user_input1);
  $img2 = imagecreatefromgif($user_input2);
  imagecolormatch($img1, $img2);

is prone to the OOB, which might be possible.  I'll investigate.
 [2018-12-09 23:05 UTC] sscannell at ripstech dot com
Thank you very much for your fast reply & creating the second test script that demonstrates the possibility of remote attacks! 

The test script I posted here was intended for local exploitation @cmb.
 [2018-12-11 18:13 UTC] cmb@php.net
-Status: Assigned +Status: Verified
 [2018-12-11 18:13 UTC] cmb@php.net
It is indeed possible that an image (at least PNG and GD) can be
loaded which uses palette indexes greater than or equal to
im->colorsTotal, see the exploit PoC[1].

I'm not sure, though, whether this should be fixed in the image
loading functions, or in gdImageColorMatch().  Interestingly,
there is some debug code which checks for this bad condition[2],
so perhaps being able to load such images is intended.  On the
other hand, that doesn't seem to make sense.

Anyhow, I'm going to forward this issue to security@libgd.org;
let's see if they have something to add.

[1] <https://gist.github.com/cmb69/911de73cc2fbdad85570ea7143455457>
[2] <https://github.com/php/php-src/blob/php-7.3.0/ext/gd/libgd/gd_png.c#L417-L423>
 [2018-12-30 02:56 UTC] stas@php.net
@cmb: any news about this one? Would be nice to get some resolution towards final 5.6 release.
 [2018-12-30 13:13 UTC] cmb@php.net
-Assigned To: cmb +Assigned To: stas
 [2018-12-30 13:13 UTC] cmb@php.net
I have not yet received any reply to my mail to the security
mailing list of libgd sent on 2018-12-11.  Of course, we could
apply a patch[1] to our bundled libgd, but builds against upstream
libgd would still be vulnerable.

[1] <https://gist.github.com/cmb69/1f36d285eb297ed326f5c821d7aafced>
 [2019-01-03 06:26 UTC] stas@php.net
The patch seems to be for 7.2+, but 5.6+ also has gdImageColorMatch. 
Backported to 5.6 as e7fac98af057f6135998c6f8c8ba520204069329 in security repo, and I'll apply original one (differs only in filename) to 7.2
 [2019-01-07 08:10 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7a12dad4dd6c370835b13afae214b240082c7538
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:10 UTC] stas@php.net
-Status: Verified +Status: Closed
 [2019-01-07 08:19 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=567c9f58425c37260864f276b6d3f434eecf4b49
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:19 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7a12dad4dd6c370835b13afae214b240082c7538
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=567c9f58425c37260864f276b6d3f434eecf4b49
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7a12dad4dd6c370835b13afae214b240082c7538
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=567c9f58425c37260864f276b6d3f434eecf4b49
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:20 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7a12dad4dd6c370835b13afae214b240082c7538
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:21 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=567c9f58425c37260864f276b6d3f434eecf4b49
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 08:21 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7a12dad4dd6c370835b13afae214b240082c7538
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-07 13:17 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=a15af81b5f0058e020eda0f109f51a3c863f5212
Log: Fix #77270: imagecolormatch Out Of Bounds Write on Heap
 [2019-01-27 18:07 UTC] sscannell at ripstech dot com
Hi!

I just wanted to add that this has issue in libgd has been assigned CVE-2019-6977.

https://nvd.nist.gov/vuln/detail/CVE-2019-6977
 [2019-01-27 19:00 UTC] kaplan@php.net
-CVE-ID: +CVE-ID: 2019-6977
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun May 19 14:01:26 2019 UTC