php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #74704 PNG PLTE Chunk ability to inject malicious code
Submitted: 2017-06-07 13:24 UTC Modified: 2017-10-15 22:40 UTC
From: daniel dot kalinowski at llamasbytes dot com Assigned:
Status: Not a bug Package: GD related
PHP Version: 7.0.19 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: daniel dot kalinowski at llamasbytes dot com
New email:
PHP Version: OS:

 

 [2017-06-07 13:24 UTC] daniel dot kalinowski at llamasbytes dot com
Description:
------------
Hello,I have noticed that many developers relays on imagepng() function when it comes to security. That function detects if image file is correct, therefore in some cases it prevents attacker from uploading a malicious image,saving it, etc. 

I want to share with you with technique that allows to put malicious code in the PNG file that will not get stripped out by imagepng(). 

Attacker need to generate an index based PNG file with palette of colours.
Colours order should be equal to hex encoded payload. 

Example:
Payload = "foobar"
hex="666f6f626172"
subtract hex by 6 to get the colours.
First colour: 666f6f 
Second colour: 626172

Now we can supply that file to imagepng() function.

Everything is in accordance with specifications ;) 

Recommendations:
Read the order of PLTE in random order to prevent that kind of attack vector. 
Specifications of the PNG(https://www.w3.org/TR/PNG/#11PLTE) doesn't mention anything about order of the colors in PLTE chunk. 

Test script:
---------------
Source image:
http://demo.llamasbytes.com/php/in.png
Java code (Payload generator)
http://demo.llamasbytes.com/php/PngChunks.java
PHP code:
//test.php
<?php
$im =imageCreateFromPng('out.png');
imagepng($im);
 ?>
Bash:
php test.php > mal.png

Expected result:
----------------
Open the output file(mal.png) of the script(test.php) in hexeditor and check that PLTE chunk still contains malicious code. 

Some examples:
http://demo.llamasbytes.com/php/mal_php_shell.png
http://demo.llamasbytes.com/php/mal_phpinfo.png


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-06-07 16:21 UTC] cmb@php.net
> I have noticed that many developers relays on imagepng()
> function when it comes to security.

They shouldn't rely solely on this, though. While the technique to
put malicious code in the PLTE chunk is a simple way to do so, any
chunk could contain malicious code[1], even the IDAT chunk might,
and if the image is saved with the same compression level than the
uploaded image, this code would survive.

Therefore I don't think this is something to be catered to in
libgd, but rather by application developers.

<https://www.w3.org/TR/PNG/#13Security-considerations>
 [2017-06-07 16:35 UTC] daniel dot kalinowski at llamasbytes dot com
>If the image is saved with the same compression level than the
uploaded image, this code would survive.

Yeah you are right, but PLTE survive even if compression level is changed.
Ok so i will do a writeup about it soon. 
Can you provide me with some code that will defend developer from this attack vector ?
 [2017-06-07 17:21 UTC] stas@php.net
-Status: Open +Status: Not a bug
 [2017-06-07 17:21 UTC] stas@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions.  Due to the volume
of reports we can not explain in detail here why your report is not
a bug.  The support channels will be able to provide an explanation
for you.

Thank you for your interest in PHP.

I don't see how it is a PHP bug. imagepng() was never intended to be a security filter or provided any guarantees as to stripping any kinds of payloads. So I don't think there's anything to do on PHP side. It may be possible to add specific function to sanitize png images but that'd be a feature request to libgd developers.
 [2017-06-07 19:29 UTC] daniel dot kalinowski at llamasbytes dot com
Ok,thanks for your opinion! 
Regards,
Daniel.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 07:01:28 2024 UTC