什么是序列化?为什么几乎所有语言都有序列化功能

实序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是IO,而我们的IO支持的数据格式就是字节数组。

因为我们单方面的只把对象转成字节数组还不行,因为没有规则的字节数组我们是没办法把对象的本来面目还原回来的,所以我们必须在把对象转成字节数组的时候就制定一种规则(序列化),那么我们从IO流里面读出数据的时候再以这种规则把对象还原回来(反序列化)

1
2
3
4
5
6
7
8
9
10
11
<?php
class aaaa{
public $name;
function __construct($name)
{
$this->name=$name;
}
}
$obj= new aaaa( name: "kaede");
echo serialize($obj);
?>

这就是php反序列化中的pop链

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class aaaa{
public $name;
function __construct($name)
{
$this->name=$name;
}
}
$obj= new aaaa( name: "kaede");
$data='O:4:"aaaa":1:{s:4:"name";s:5:"kaede";}';
$aaa=unserialize($data);
var_dump($aaa);
?>

对上述代码进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class aaaa{
public $name;
public $code;
function __construct($name)#假设一个程序的函数点是可以调用的,那么我们直接构造pop链子
{
$this->code='phpinfo();';
$this->name=$name;
}
}
$obj= new aaaa( name:"kaede");
echo serialize($obj);
?>
1
O:4:"aaaa":2:{s:4:"name";s:5:"kaede";s:4:"code";s:10:"phpinfo();";}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class aaaa{
public $name;
public $code;
function __construct($name)
{
$this->code='var_dump(123);';
$this->name=$name;
}
function __toString()
{
return eval($this->code);
}
}
$data='O:4:"aaaa":2:{s:4:"name";s:5:"kaede";s:4:"code";s:10:"phpinfo();";}';
$ob=unserialize($data);
echo $ob;

那就成了

各种编程语言中的反序列化漏洞

几乎所有语言都存在反序列化漏洞,说实话,很难修复

反序列化的分类

反序列化执行触发任意代码——python

反序列化后,通过已有代码利用链,间接执行任意代码—php,java

那么,该如何挖掘反序列化

其实也简单,就是找serialize和unserialize以及十六个魔术方法,你都打反序列化了,总不可能是黑盒罢

php反序列化特点

  • 引入除资源型任意类型变量
  • 无法引入函数->不能直接执行代码
  • 迂回战术

寻找程序中可能存在的漏洞类

实例化对象->触发漏洞

php反序列化后可能执行的方法

  • __wakeup:反序列化操作执行后触发
  • __destruct:类对象销毁时触发
  • __tostring:类对象转换为字符串时触发

漏洞挖掘过程

寻找调用反序列化函数的位置

寻找包含危险方法的类

反序列化上下文是否包含该类

包含:直接生成该类,触发漏洞

不包含:寻找引用链

例子:wecenter反序列化造成任意sql语句执行

https://www.leavesongs.com/PENETRATION/wecenter-unserialize-arbitrary-sql-execute.html