PHP反序列化漏洞学习

时间:2022-07-23
本文章向大家介绍PHP反序列化漏洞学习,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

类似前言一样的东西

在很多CTF题目上或者一些实际环境中都有碰到过反序列化漏洞,但是看到那些乱七八糟的就感觉学不进去,趁着暑假时间多的时候,研究一番,这篇也算是学习笔记,主要内容有:

什么是序列化和反序列化 为什么要用到序列化 产生这个漏洞的原因

什么是序列化和反序列化

在PHP中,实现序列化和反序列化,主要是靠 serialize()unserialize()这两个函数,序列化做的工作就是,将一个一个对象变成一个可传输字符串,json就是一种序列化,而反序列化的工作就是将字符串再变回对象

序列化和反序列化有点像Python中的 encode()decode(),编码和解码,只不过这两个处理的都是字符串

举一个例子:

<?php
class test{
public $name = "Elapse";
public $age = "18";
}
$example=new test();
$t = serialize($example);
echo $t;
?>

$example实例化test对象

内容为 {"name":"Elapse","age":"18"}

在实际环境中,可能需要对内容进行修改,如下:

<?php
class test{
public $name = "Elapse";
public $age = "18";
}
$example=new test();
$example->name="Ernket";
$t = serialize($example);
echo $t;
?>

如果我们想要将内容传输出去的话,则需要将内容序列化,变成一串字符串后才可发送

也可以将变量储存,有需要的时候在拿出来使用,而不是二次调用,浪费系统资源

PHP中可以通过 unserialize()来将字符串转为对象,然后调出内容

<?php
class test{
public $name = "Elapse";
public $age = "18";
}
$example=new test();
$example->name="Ernket";
$t = serialize($example);
$a=unserialize($t);
echo $a->name;
?>

产生漏洞的原因

那么上面清楚了序列化和反序列化后,这里就讲一哈反序列化漏洞产生的原因

PHP中,会产生这个漏洞的一大问题,在于PHP的魔法函数,魔法函数会因为某些条件的触发而自动执行某些指定的操作

__construct()当一个对象创建时被调用 __destruct()当一个对象销毁时被调用 __toString()当一个对象被当作一个字符串使用 __sleep() 在对象在被序列化之前运行 __wakeup将在序列化之后立即被调用

举一个任意命令执行的例子

<?php
class A{
    var $test = "ls";
    function __destruct(){
            system($this->test);
    }
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>

__destruct()为当一个对象销毁时被调用,而我们可以通过反序列化的时候,调用A对象,因为PHP魔法函数的缘故,他会自动执行__destruct()的内容,接着就是system()部分

所以通过反序列化,就可以做到控制test这个变量,从而达到任意命令执行

====分割线====

参考链接:https://www.freebuf.com/articles/web/167721.html https://www.imooc.com/article/33036 https://www.freebuf.com/column/182293.html