大家好,我是Dest1ny,php反序列化的基础篇收到了大家很多的好评,在这里非常感谢大家!
我这里准备接着基础篇去讲一些进阶一点点点,今天讲的是session反序列化。
如果对Dest1ny写的文章比较喜欢的话,各位大佬不要吝啬自己的收藏和点赞。
您的支持是我最大的动力,废话不多直接开整!
CALSS-1 关于session反序列化
我们按照惯例先看一下比较正经的解释:
概念
-
Session的序列化:
当用户通过PHP的$_SESSION
变量存储数据时,PHP会自动将这些数据序列化(即转换成字符串)并存储在服务器端的Session文件或其他Session存储介质中。序列化的格式通常是可以通过serialize()
函数手动生成的格式。 -
Session的反序列化:
当用户再次访问Session数据时,PHP会自动从服务器端读取Session文件,并通过unserialize()
函数将数据转换回原始格式。这样,开发者可以像操作普通变量一样处理$_SESSION
中的数据。
安全性问题
Session反序列化存在潜在的安全隐患,尤其是在数据没有经过适当验证的情况下,可能会导致反序列化漏洞。攻击者可能通过伪造的序列化数据或操纵Session内容,使反序列化的对象触发任意代码执行(RCE),导致严重的安全问题。
这里大家就先看一下,我是不想看哈哈哈,直接上例题!
CLASS-2 关于session的例题
这是例题,大家请签收
index.php:
<?php
highlight_file(__FILE__);
/*hint.php*/
session_start();
class Flag{
public $name;
public $her;
function __wakeup(){
$this->her=md5(rand(1, 10000));
if ($this->name===$this->her){
include('flag.php');
echo $flag;
}
}
}
?>
ok,我们现在也先读代码,至少得知道代码是干什么的:
1. 首先这里有一个flag的类,类里面有两个属性,是name和her。
2. 这里有一个wakeup()的魔法函数,这个魔法函数要字符串被反序列化时会被触发。
3. wakeup里把her的值随机赋成一个1-10000之间的数字。
4. 如果name的值和her的值相等,则会输出flag。
大致就是这个样子,其实很简单,我们只要通过上次讲的引用的知识点,让name和her指向同一个人的地址就可以强行相等!
可是代码中大家好像没看见可以去传参的地方,那怎么办?我们看见还有一个hint.php,这里肯定有提示!
CLASS-3 hint.php来了
我们访问一下hint.php
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['a'] = $_GET['a'];
?>
诶,这里可以用get传参数诶!
但是我怎么通过这个get传参,去改变index.php类里面的属性值呢?
我们先读一下代码!
-
显示源代码:它使用
highlight_file()
显示当前PHP文件的源码,便于查看文件内容。 -
关闭错误报告:通过
error_reporting(0)
关闭了所有错误报告,这样即使代码出错,用户也看不到错误提示。 -
设置Session序列化方式:使用
ini_set('session.serialize_handler', 'php_serialize')
将Session的序列化方式设置为php_serialize
,意味着PHP会使用默认的序列化方法来存储和检索Session数据。 -
启动Session:通过
session_start()
开启了一个新的Session或恢复现有的Session。 -
存储GET参数:将用户通过
GET
方法传入的参数a
存储到Session中,即$_SESSION['a'] = $_GET['a']
。用户可以通过访问类似?a=value
的URL将值传递给Session。
这里就要导入seesion的概念了!
CLASS-4 session来了!
我们看一下
这个是两个get传参,一个是ben,一个是b。然后我们看到是用session方式去读,什么意思呢?
这样我们先传参数看看!
http://127.0.0.1:8088/class20/2.php?ben=111&b=111
去容器里面看一下发生了什么
我们发现容器里面多了sess开头的文件,里面存放着序列化的字符串,然后$_SESSION这里会去把文件里的内容反序列化。
session的读取方式是不一样的,我们这里是最普通的:
这里是php_serialize,我给大家发个表就知道了:
这里我们是php_serialize的读取方式,就是直接读取session文件里的内容进行反序列化。
那思路来了,我们是不是只要通过hint.php里的a传参,因为是用session方式去解析a的传参,所以意思是不是我可以通过session反序列化的功能去修改index.php里的flag类中的属性。OKOK,直接尝试!
CLASS-5 利用session反序列化漏洞
我们先通过index.php构造一个常规的序列化字符串
这里使用了引用的方法将$name和$her的值指向到一起!
现在我们通过hint.php的session反序列的功能,去尝试将构造好的payload可以被调用起来,不然我序列化出来的东西,连个可以反序列化的机会都没有!
这里我们注意下它session读的格式:
hint.php是用php_serialize的,index.php是没说就是用默认php的方式。php和php_serialize不一样,它读取的规则是在“|”后面才可以去反序列化。
所以思路是:
hint.php会通过session反序列化去生成一个文件,按道理来说什么都可以写,因为没有什么限制。
index.php是用php去读去,而且只反序列化“|”之后的内容。所以说我的payload完整的格式是:
http://127.0.0.1:8088/class21/hint.php?a=|O:4:%22Flag%22:2:{s:4:%22name%22;N;s:3:%22her%22;R:2;}
我在a的最前面加上了|符号,那么index.php去读的时候就可以完整的把我payload读下来。
我们可以看一下内部:
看到了吗,正好就把payload全部可以反序列化,这个时候我们只要刷新一下index.php就可以,因为内部值已经被改了。
OK,结束!!
我是Dest1ny,制作不易,各位大佬多多点赞支持!!!!