翻译有限,请以原文内容为准
回顾关于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()是极度禁止的,但仍有很多真实案例
- Pydio unauthenticated Remote Code Execution.
- WooCommerce Privilege Escalation.
- PrestaShop Remote Code Execution.
- SugarCRM Multiple Vulnerabilities.
- ExpressionEngine Remote Code Execution.
未完…还需拓展