有关如何通过工具链expoit PHP对象注入

翻译有限,请以原文内容为准

回顾关于php的序列化问题

php提供一种通过php类型存储和加载数据的机制。这种机制归结为如下两个方法:

  • serialize()
A PHP object being ‘serialized’

<?php
$object = new stdClass();
$object->data = "Some data!";
$cached = serialize($object);
The resulting ‘serialized’ string

O:8:"stdClass":1:{s:4:"data";s:10:"Some data!";}

以上两个步骤是创建一个新对象然后用 ‘序列化’ 的字符串表示这个对象。
‘O’表示对象、‘8’表示对象名字长度(本例创建了一个stdClass 实例)
‘1’表示对象多包涵的属性个数
属性由属性名和属性值组成,属性名是字符串形式,属性值则可以是任意类型,arrays, integers, strings, objects and NULL是常见类型

  • unserealize()
The serialized string being ‘unserialized’ again

<?php
$object = unserialize('O:8:"stdClass":1:{s:4:"data";s:10:"Some data!";}');
echo $object->data;

上面的代码是php会将序列化字符串解析成一个stdClass并带有后面相应属性的实例。

开发者这样做的原因是为了简单高效的在缓存或数据库中存储resquest请求 (比如一个userSession可以被应用为一个class UserSession的实例,这个对象可以很容易的被存储在$_session这个全局变量中,并且随时调用)

关于反序列化的危害

危害发生场景:当用户输入被传进unserialize(),就可能会构成远程代码执行漏洞。

首先,php解释器有很多低级安全问题 low-level security issues可以被利用

另外根据实际web应用的代码,攻击者也有很多其他的办法。举例如下:

The serialized string being ‘unserialized’ again

<?php
class LoggingClass {

    function __construct($filename, $content) {
        // add .log to the filename so we are really creating a log file!!
        $this->filename = $filename . ".log";
        $this->content = $content;
    }
    
    // This method is executed for each object at the end of the PHP execution
    function __destruct() {
        // flush the logs
        file_put_contents($this->filename, $this->content);
    }

}

$data = unserialize($_GET['data']);

可以看到用户的get请求直接作为unserialize()的输入参数

一些细节

前图的代码里:
LoggingClass:构造函数含有两个参数,一个表文件名,一个表稳文件内容。
__destruct(): 每创建一个LoggingClass对象,在代码结束时__destruct()会自动执行。

截至目前,虽然攻击者可以控制文件内容但是限于文件后缀是.log,无法执行恶意内容。(如果没有这层设置,那么直接命名为shell.php就好了)

然而,如果攻击者将如下内容作为unserialize()参数

A serialized payload

O:12:"LoggingClass":2:{s:8:"filename";s:9:"shell.php";s:7:"content";s:20:"<?php evilCode(); ?>";}

可以看到:filename属性 value设置为“shell.php”

通过修改对象属性直接调用file_put_contents(),达到留下后门的目的。

更多的攻击方式:

实际案例

虽然直接将用户输入传参进unserialize()是极度禁止的,但仍有很多真实案例

未完…还需拓展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值