0x02 反序列化漏洞利用
反序列化漏洞的成因在于代码中的 unserialize() 接收的参数可控,从上面的例子看,这个函数的参数是一个序列化的对象,而序列化的对象只含有对象的属性,那我们就要利用对对象属性的篡改实现最终的攻击。
01对象注入
当用户的请求在传给反序列化函数unserialize()
之前没有被正确的过滤时就会产生漏洞。因为PHP允许对象序列化,攻击者就可以提交特定的序列化的字符串给一个具有该漏洞的unserialize
函数,最终导致一个在该应用范围内的任意PHP对象注入。
对象漏洞出现得满足两个前提:
一、
unserialize
的参数可控。
二、 代码里有定义一个含有魔术方法的类,并且该方法里出现一些使用类成员变量作为参数的存在安全问题的函数。
<?php
class A{
var $test = "demo";
function __destruct(){
echo $this->test;
}
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>
比如这个列子,直接是用户生成的内容传递给unserialize()函数
,那就可以构造这样的语句
?test=O:1:"A":1:{s:4:"test";s:5:"lemon";}
在脚本运行结束后便会调用_destruct
函数,同时会覆盖test变量输出lemon。
发现这个漏洞,便可以利用这个漏洞点控制输入变量,拼接成一个序列化对象。
再看下面这个例子:
<?php
class A{
var $test = "demo";
function __destruct(){
@eval($this->test);//_destruct()函数中调用eval执行序列化对象中的语句
}
}
$class = $_GET['class'];
$test_unser = unserialize($class); // 反序列化同时触发_destruct函数
?>
其实仔细观察就会发现,其实我们手动构造序列化对象就是为了unserialize()函数
能够触发__destruct()
函数,然后执行在__destruct()
函数里恶意的语句。
所以我们利用这个漏洞点便可以获取web shell了
<img src="/Users/zhoumengying/Documents/imgs/unserialzer1.png" alt="在这里插入图片描述" style="zoom:50%;" />
02其他Magic function的利用
但如果一次unserialize()中并不会直接调用的魔术函数,比如前面提到的__construct(),是不是就没有利用价值呢?非也。类似于PWN中的ROP,有时候反序列化一个对象时,由它调用的__wakeup()中又去调用了其他的对象,由此可以溯源而上,利用一次次的“fuzz”找到漏洞点
<?php
class test{
function __construct($test){
$fp = fopen("shell.php","w") ;
fwrite($fp,$test);
fclose($fp);
}
}
class test2{
var $test = '123';
function __wakeup(){
$obj = new test($this->test);
}
}
$class = $_GET['test'];
$class5_unser = unserialize($class);
03 普通方法的使用
前面谈到的利用都是基于“自动调用”的magic function。但当漏洞/危险代码存在类的普通方法中,就不能指望通过“自动调用”来达到目的了。这时的利用方法如下,寻找相同的函数名,把敏感函数和类联系在一起。
<?php
class fengxuan {
var $test;
function __construct() {
$this->test = new class2();
}
function __destruct() {
$this->test->action();
}
}
class class2 {
var $test2;
function action() {
eval($this->test2);
}
}
$class6 = new fengxuan();
unserialize($_GET['test']);
?>
本意上,new一个新的fengxuan对象后,调用__construct(),其中又new了class2对象。在结束后会调用__destruct(),其中会调用action(),从而执行代码。
04反序列化高级攻击
phar:// 如何扩展反序列化的攻击面的
来自2017 年的 hitcon Orange 的一道 0day 题
原来 phar 文件包在 生成时会以序列化的形式存储用户自定义的 meta-data ,配合 phar:// 我们就能在文件系统函数 file_exists() is_dir() 等参数可控的情况下实现自动的反序列化操作,于是我们就能通过构造精心设计的 phar 包在没有 unserailize() 的情况下实现反序列化攻击,从而将 PHP 反序列化漏洞的触发条件大大拓宽了,降低了我们 PHP 反序列化的攻击起点。
<img src="https://picture-1253331270.cos.ap-beijing.myqcloud.com/phar%20manifest.png" alt="此处输入图片的描述" style="zoom:80%;" />
通过以上的例子总结一下寻找 PHP 反序列化漏洞的方法或者说流程
(1) 寻找 unserialize() 函数的参数是否有我们的可控点
(2) 寻找我们的反序列化的目标,重点寻找 存在 wakeup() 或 destruct() 魔法函数的类
(3) 一层一层地研究该类在魔法方法中使用的属性和属性调用的方法,看看是否有可控的属性能实现在当前调用的过程中触发的
(4) 找到我们要控制的属性了以后我们就将要用到的代码部分复制下来,然后构造序列化,发起攻击
0x03 防御措施
1.严格的把控 unserailize() 函数的参数,不要给攻击者任何输入的可能
2.在文件系统函数的参数可控时,对参数进行严格的过滤。
3.严格检查上传文件的内容,而不是只检查文件头。
4.在条件允许的情况下禁用可执行系统命令、代码的危险函数。
0x04 参考
http://blog.evalshell.com/2021/01/05/风炫安全web安全学习第四十节课-反序列化漏洞攻击/
网友评论