用于对象注入的PHP serialize()

时间:2015-12-17 12:38:45

标签: php object serialization code-injection exploit

我目前正在分析名为PHP Object Injection的PHP开发方法,该方法允许修改已定义的对象,因为unserialize()函数中有未经过输入的输入。

以下是代码:

<?php

class foo {}
class SuperClass {}

$ss = 'O:3:"foo":2:{s:4:"test";b:1;s:2:"fg";O:10:"SuperClass":0:{}};';

print_r(unserialize($ss));

?>

产生以下输出:

foo Object
(
    [test] => 1
    [fg] => SuperClass Object
        (
        )

)

我的问题是,如何重新创建我可以传递给serialize()函数的对象结构,该函数会创建相同的输入字符串? PHP不允许嵌套类,所以我很困惑如果甚至可以使用serialize()生成这样的字符串?

以下是我将如何做到这一点,但由于PHP不允许嵌套类,它将无法工作:

class foo {

    public $test = 1;
    public $fg = class SuperClass {

    }

}

echo serialize(new foo);

2 个答案:

答案 0 :(得分:3)

如果你想看看PHP如何序列化这样的类结构,那就是我假设你要求然后创建这样的类

<?php

class SuperClass
{
    public $name = 'SuperClass';
}

class foo
{
    public $name = 'foo';
    public $test = 1;

}

$s = new SuperClass();
$f = new foo();

$s->fg = $f;

$ss = serialize($s);

echo $ss . PHP_EOL;

$hydrated = unserialize($ss);

print_r($hydrated);

这会产生以下输出

O:10:"SuperClass":2:{s:4:"name";s:10:"SuperClass";s:2:"fg";O:3:"foo":2:{s:4:"name";s:3:"foo";s:4:"test";i:1;}}

SuperClass Object
(
    [name] => SuperClass
    [fg] => foo Object
        (
            [name] => foo
            [test] => 1
        )

)

您可以使用此方法来查看如何操作序列化字符串以向字符串添加任何内容,以使对象包含您想要的任何内容。

答案 1 :(得分:0)

可能这些字段必须是该类的实例。

class foo {

    public $test = 1;
    public $fg = new SuperClass();
}

var_dump(serialize(new foo()));

除了语法之外,PHP7还提供了匿名类功能

public $fg = new class() extends SuperClass {
                // some additional implementation here
}

因此,您可以添加稍后将在序列化字符串中显示的字段。在当前示例中,不存在任何一个。