PHP反序列化漏洞

PHP反序列化漏洞是指在PHP应用程序中由于不正确地处理用户提供的序列化数据而导致的安全漏洞。这种漏洞通常出现在接受用户输入并将其反序列化为对象或数据结构的地方,比如通过unserialize()函数。

  攻击者可以利用这种漏洞在服务器上执行恶意代码,进行远程代码执行(RCE)攻击,获取系统权限,甚至完全控制受影响的服务器。

1.面向对象与面向过程的优缺点

面向对象:

         优点:不仅关注眼前的事件实现,也关注未来可能发生的事件。具有高度的拓展性和复用性,特点是继承、封装、多态。
         缺点:如果只是单一的功能实现,面向对象的设计思路会较为繁琐

面向过程:

         优点:根据事情的目的分解出过程,再一步步实施。对于不复杂的事件执行效率快。
         缺点:只关注眼前事件的实现,开发复杂功能的时候繁琐。

2.类和对象的关系

类和对象之间有密切的关系,可以简单地概括为“类是对象的蓝图,对象是类的实例”。

  • 类(Class) 是一种抽象的数据类型,它定义了一组属性(成员变量)和方法(成员函数)。类是一种模板或蓝图,描述了对象应该具有的属性和行为。

  • 对象(Object) 是类的实例化。当一个类被实例化时,就创建了一个对象。对象是类的具体实体,具有类定义的属性和方法。

  类定义了对象的属性和方法,而对象则是这些属性和方法的实际实例。类是一种抽象的概念,它描述了对象应该有什么样的属性和行为,而对象则是具体的实例,它实际上拥有这些属性和行为。

举个例子:

class Car {
    // 属性
    public $color;
    public $brand;

    // 方法
    public function start() {
        echo "Car started!";
    }

    public function stop() {
        echo "Car stopped!";
    }
}

// 创建Car类的实例(对象)
$myCar = new Car();
$myCar->color = "red";
$myCar->brand = "Toyota";

// 调用对象的方法
$myCar->start();

在这个例子中,Car 是一个类,它定义了汽车的属性(color 和 brand)以及行为(start() 和 stop() 方法)。当我们创建 $myCar 对象时,它就是 Car 类的一个实例,拥有类定义的属性和方法。

3.php访问修饰符

在php类中不写访问修饰符默认的访问权限为public

在 PHP 中,访问修饰符用于定义类的属性和方法的访问级别。这些修饰符包括:

  1. public(公共):公共成员可以在任何地方被访问,没有访问限制

  2. protected(受保护):受保护的成员只能被定义它们的类或继承该类的子类访问。外部类不能直接访问受保护成员

  3. private(私有):私有成员只能被定义它们的类访问。外部类和子类都不能直接访问私有成员

这些访问修饰符可以用来控制类的封装性,确保类的内部数据不被外部类或代码直接访问和修改,从而提高代码的安全性和可维护性。在 PHP 中,访问修饰符使用关键字 publicprotectedprivate 来定义。例如:

class MyClass {
    public $publicVar;
    protected $protectedVar;
    private $privateVar;

    public function __construct() {
        $this->publicVar = "Public variable";
        $this->protectedVar = "Protected variable";
        $this->privateVar = "Private variable";
    }

    public function getPrivateVar() {
        return $this->privateVar;
    }
}

$obj = new MyClass();

echo $obj->publicVar; // 可以正常访问
// echo $obj->protectedVar; // 无法直接访问,会导致错误
// echo $obj->privateVar; // 无法直接访问,会导致错误
echo $obj->getPrivateVar(); // 可以通过公共方法访问私有属性的值

publicVar 是公共属性,可以在任何地方访问。protectedVar 是受保护属性,只能在该类或其子类中访问。privateVar 是私有属性,只能在该类内部访问

4.php序列化和反序列化

在 PHP 中,序列化是将数据结构或对象转换为字符串的过程,而反序列化则是将这个字符串重新转换为原始的数据结构或对象的过程。这种转换通常用于在不同的应用程序之间或在不同的请求之间传递数据,或者用于将数据持久化存储

PHP 中有两个主要的函数来执行序列化和反序列化操作:

1.序列化(Serialization): 使用 serialize() 函数将数据结构或对象转换为字符串。

$data = array('name' => 'John', 'age' => 30, 'city' => 'New York');

$serializedData = serialize($data);

echo $serializedData; 

在上面的例子中,$data 数组被序列化为一个字符串,并存储在 $serializedData 变量中。

2.反序列化(Unserialization): 使用 unserialize() 函数将序列化后的字符串重新转换为原始的数据结构或对象。

$serializedData = 'a:3:{s:4:"name";s:4:"John";s:3:"age";i:30;s:4:"city";s:8:"New York";}';

$unserializedData = unserialize($serializedData);

print_r($unserializedData);

在上面的例子中,$serializedData 字符串被反序列化为原始的数组,并存储在$unserializedData 变量中。

5.php魔术方法

PHP的魔术方法(Magic Methods)是一组特殊的方法,以双下划线(__)开头和结束命名的。

它们在对象的生命周期中被自动调用,用于执行特定的操作。这些魔术方法可以让开发者更好地控制和定制对象的行为

__construct(), 类的构造函数,创建对象时进行初始化操作
__destruct(),   类的析构函数,在对象被销毁(即失去对对象的所有引用)之前执行一些清理操作
__call(),            在对象中调用一个不可访问或不存在方法时调用
__callStatic(),  调用一个不可访问或不存在的静态方法时调用
__get(),            访问一个对象的不可访问或不存在属性时调用
__set(),            对不可访问属性进行赋值时调用
__isset(),         当对不可访问或不存在属性调用isset()或empty()时调用
__unset(),       当对不可访问或不存在属性调用unset()时被调用。
__sleep(),        执行serialize()之前,先会调用这个函数
__wakeup(),   执行unserialize()之后调用这个函数
__toString(),   类被当成字符串时的回应方法
__invoke(),     用于将一个对象作为函数直接调用时的行为定义。
__set_state(),设置对var_export() 函数所产生的字符串的进行反序列化操作时行为。
__clone(),       当clone 关键字复制一个对象时调用
__autoload(), 尝试加载未定义的类
__debugInfo(),   打印所需调试信息

php允许在变量后面加括号来调用方法

5.靶场

靶场环境搭建

网站:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场

这里用docker搭建

docker pull mcc0624/ser:1.8     #拉取镜像

docker images         #显示当前存储在系统本地的镜像

docker run -d -p 8002:80 c81     #运行镜像

docker ps     #列出所有正在运行的docker容器

访问IP地址:8002

192.168.168.128:8002

搭建完成

1.反序列化漏洞例题

该代码接收一个名为benben的参数然后将参数的值反序列化为对象再调用生成对象的displayVar方法

<?php
highlight_file(__FILE__);
error_reporting(0);
class test{
    public $a = 'echo "this is test!!";';
    public function displayVar() {
        eval($this->a);
    }
}

$get = $_GET["benben"];
$b = unserialize($get);
$b->displayVar() ;

?> 

test对象的displayVar方法会将自身的a变量传入eval方法中,造成代码执行
只要控制a的值,即可达到任意代码执行
而题目没有对序列化过程做任何干预,直接构造a的值进行序列化后传入即可

执行1.php

PHP在反序列化的时候,它只会反序列化属性,不会反序列化行为,因为我们可以发现在类实例化到对象的过程中,只有我们的属性产生了赋值,我们的方法是不变的

2.析构函数例题

执行1.php

3.__wakeup()例题

执行1.php

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
关于PHP反序列化漏洞的习题,可以使用GlobIterator类和ArrayObject类来进行练习。其中,GlobIterator类的题目是被遗忘的反序列化,ArrayObject类的题目是easy_phpPHP反序列化漏洞是一种安全漏洞,其中一个具体的例子是CVE-2016-7124,该漏洞存在于php5<5.6.25和php7<7.0.10的版本中。漏洞的产生原因是由于反序列化时对输入的不当处理所导致的。 了解PHP反序列化漏洞的习题,需要掌握类与对象、反序列化基础知识以及一些与魔术方法相关的内容,如构造和折构方法(__construct()、__destruct())、序列化和反序列化方法(__sleep()、__wakeup())、错误调用魔术方法(__callStatic()、__get()、__set()、__isset()、__unset()、__clone())等。反序列化漏洞的成因较复杂,例如POP链构造、POC链反推法等。 此外,还可以学习字符串逃逸和__wakeup魔术方法绕过漏洞的相关知识。其中,__wakeup魔术方法绕过漏洞的产生原因是__wakeup方法可以在反序列化时被绕过,从而可能导致安全漏洞PHP反序列化漏洞还可以通过引用的利用方法来进行学习。另外,还可以学习SESSION反序列化漏洞和phar反序列化漏洞的习题。其中,SESSION反序列化漏洞涉及到不同处理器的不同储存格式,而phar反序列化漏洞需要了解phar的构造和使用条件。 通过这些习题的学习,可以更好地理解PHP反序列化漏洞以及如何进行防范和修复。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [PHP反序列化漏洞(最全面最详细有例题)](https://blog.csdn.net/m0_73728268/article/details/129893800)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lin___ying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值