php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #71459 Integer overflow in iptcembed()
Submitted: 2016-01-27 00:56 UTC Modified: 2016-02-02 03:17 UTC
From: stas@php.net Assigned: stas
Status: Closed Package: *Graphics related
PHP Version: 5.5.31 OS: *
Private report: No CVE-ID:
 [2016-01-27 00:56 UTC] stas@php.net
Description:
------------
Reported by Jurriaan Bremer:

Given one is able to execute a PHP file there exists a trivial heap
overflow in the `ext/standard/iptc.c` module, a module which exports
the `iptcembed` and `iptcparse` functions. It should be noted that the
implementation of these functions is - in some countries - allowed to
drink beer and get driving lessons.

Initially implemented in the good ol' [Internet bubble][impl] it has
since been [patched][] as the function showed too much power to the
internet as it was mastering the heap in ways not seen before. Since
then [a][p0] [number][p1] [of][p2] [clear][p3] [improvements][p4] have
been seen while still remaining heap master in disguise.

[impl]:
https://github.com/php/php-src/commit/ad0076ee5318bba0c055c28271d6810c53
db6f40#diff-98113f2c152c3d95d366989462658a39R232
[patched]:
https://github.com/php/php-src/commit/ec33704c3929fc874ef434f623a58d34ac
fffd82
[p0]:
https://github.com/php/php-src/commit/c0404f46311e5b519dc51697e181bb39ca
8d09d2#diff-98113f2c152c3d95d366989462658a39L225
[p1]:
https://github.com/php/php-src/commit/511463854b2ea520604ec22c0d0d80cc32
9727ae
[p2]:
https://github.com/php/php-src/commit/cce7545d18ed7774b3938565dd1c770c9a
14bbb9#diff-98113f2c152c3d95d366989462658a39L230
[p3]:
https://github.com/php/php-src/commit/312181bc13d99ce089aeb16542db9f6c8a
11f108
[p4]:
https://github.com/php/php-src/commit/887e5ad110eb87c3969b0e7f12a2b2fd9f
b9c0b0

Following is a POC that will trigger a memory corruption. For those
with more time on their hands it should be obvious that this can be
exploited further on 32-bit versions of PHP. Unfortunately it'd appear
that, since one is not able to `ftruncate()` a
`0xffffffffffffffff`-sized file on any filesystem (as far as I'm
aware?), it is not possible to wraparound the 64-bit length variable
that is allocated in 64-bit versions of PHP.

```php
<?php

if(file_exists("heapyolo") == 0) {
    $fp = fopen("heapyolo", "wb");

    fwrite($fp, "\xff\xd8\xff\xe0\x00\x02\x00\xd9");
    for ($i = 0; $i < 4096; $i++) {
        fwrite($fp, str_repeat("A", 1024*1024));
    }

    fclose($fp);
}

iptcembed(str_repeat("A", 1024*1024), "heapyolo");
?>
```

The POC writes a legitimate `iptc`-compatible header followed by 4 GB
of data. In combination with the constant integers and length of the
`iptcdata` the filesize then overflows the 32-bit length field which
[is then allocated][alloc].
By using the `M_APP0` switch/case entry we're then able to overwrite
heap memory with arbitrary values and arbitrary length as passed along
by the `iptcdata` variable. It should be noted that this can be done
multiple times - as long as PHP doesn't crash - and that we only have
to write the 4GB file once due to this construct.

[alloc]:
https://github.com/php/php-src/blob/master/ext/standard/iptc.c#L207

Well, that's enough The Internet for me for today. Thanks!



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-01-27 01:32 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-01-27 01:32 UTC] stas@php.net
Fixes in security repo under f379142d66885cae8b13db884ff76fe398421884 and 54c210d2ea9b8539edcde1888b1104b96b38e886. See also https://gist.github.com/smalyshev/a3519b7fdd5f6efeeea4
 [2016-02-02 03:19 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=54c210d2ea9b8539edcde1888b1104b96b38e886
Log: Fix bug #71459 - Integer overflow in iptcembed()
 [2016-02-02 03:19 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-02-02 03:36 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=54c210d2ea9b8539edcde1888b1104b96b38e886
Log: Fix bug #71459 - Integer overflow in iptcembed()
 [2016-02-02 04:46 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f379142d66885cae8b13db884ff76fe398421884
Log: Fix bug #71459 - Integer overflow in iptcembed()
 [2016-02-02 04:46 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=54c210d2ea9b8539edcde1888b1104b96b38e886
Log: Fix bug #71459 - Integer overflow in iptcembed()
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Jul 25 22:01:35 2017 UTC