当前位置:实例文章 » PHP实例» [文章]PHP之序列化与反序列化(session反序列化篇);

PHP之序列化与反序列化(session反序列化篇);

发布人:shili8 发布时间:2022-12-30 17:53 阅读次数:34

只要接触多一点web方向的话无论是在做题还是在抓包都会碰到一个词-----session,无论你见过也好听过也罢,你是否真的知道session是什么?

初识session

简单直白一点session就是会话,是服务器与客户机的一次会话。

会话可以理解为一次交流,比如我和你说“早安,你觉得今天天气怎么样”,接着你会对我说“早啊,今天是个大晴天呢!”。这就相当于一次会话,那么就疑惑了,要这玩意儿有什么用呢?

这里举个例子,小明和小红在微信上网恋,但是两个人一直只是聊天从来没有见过面,有一天,小红对小明说我们见一面吧,用一句暗号证明我们的身份,然后那天,他们见面了各自对暗号,然后认识了彼此。

故事到此结束,那么session就等同于他们的暗号也就是说客户机和服务器每进行一次会话会记录一个值赋给$_SESSION['name'],这也是为什么,如果你在登录页面输入了账号密码,当它眺转到另一个页面也是以你之前的这个登录状态执行的。

那么到这里如果有稍微懂一点的朋友肯定又会问了,“你说的这个session作用咋和cookie这么像,那都已经有cookie了还要session干嘛?”。这里就要讲cookiesession的区别了,其实session出现的话也有部分原因是因为cookie。由于cookie存在于客户端,在客户端很容易被用户看到并且可以被随意改动,如果被不安好心的人拿到就容易出事。相反session存在于服务器,正常情况下安全性还是很高的。

session的存储

虽说session是会话过程中产生了,那么它具体是怎么产生的呢?然后就要介绍session之母,session_start(),不用怀疑,这玩意和session的生成离不开干系。

session_start()的作用就是开启session并且会随机生成一个32位的session_id,如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

无论怎么刷新或者切换页面都不会改变它的session_id()值,

但是如果你关闭浏览器重新打开或者把cookie清除再刷新一下会发现:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

相比于把账户密码存在cookie中,这种一个周期的存储更加安全。当然也不是说cookie没用,各有各的妙用。

session_id的值存储在服务器的临时目录tmp/temp下,查看一下php.ini就知道路径的存储了。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16?可以看到文件名的格式是sess_+session_id()拼凑出来的。那么前面说过,session存在服务器中是无法在cookie中修改的,试试:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16?

成功了?tmp文件中也出现了。watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

但文件大小为空(0KB),我们看看能不能装点东西进去,如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

再看看文件,?

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?看文档出现的格式大概就明白了,以竖线?| 为分隔,左边为键右边为值,且右边的值会被序列化!!所以序列化不就来了吗?

我们大概梳理一下:

当HTTP请求一个页面时,其中的session_start()打开,则会寻找COOKIE中的PHPSESSION是否为空,若不为空session_id()就是这个值,若为空则随机生成一个id存入PHPSESSION中,再在临时文件目录中生成一个文件名为sess_+session_id()的文件以及将$_SESSION的键值对按照一定格式存储到文件中。

?

session的配置

?

session.auto_start,如果设置为on不需要session_start()也能自动生成一个session_id()?。watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?session.save_path文件保存路径,前面已经写过了。watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?session.serialize_handler序列化的格式?,默认为php,还可以是php_serialize或则php_binary

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?

?当设置修改为php_binary时,格式为:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16?watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?可以看到有不可见字符!!这个其实是二级制字符。

当设置为php_serialize时,格式为:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16?watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16可以看到把键值全都序列化了!!

?

?session反序列化

问题又回来了,到底怎么利用session反序列化,平时做题目的时构造的payload为什么要在最前面加个竖线 | 。这里提个问题,就是如果我们session本就打开,这时候又使用一次session_start会怎么样呢?让我们再深入看看session_start()

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?重用会话会自动反序列化?也就是自带了反序列化函数unserialize,也就是说如果我们想办法控制数据序列化后存储在sess_session_id这个文件中,那么当再次遇到了session_start()时就会出现数据反序列化,那么就能实现我们反序列化的目的了。

这个是大体思路,那么接下来要解决的是,文件内容中是不仅包含了值,还包括了键,我们应该怎么做才能使得是我们想要反序列化的数据存在值中而不是键中(为什么要存在值中:因为上面提到过,只有值才能被反序列化,键并不会)。

这里就需要介绍出两种处理器的差别了,因为PHP处理器写入时的格式为:键 + ’ | ‘ + 值的序列化,所以当它读取时判断一个字符串哪是键哪是值时是通过分隔符' | '判断的,前面的为键名,后面的为键值,然后将键值进行反序列化操作;而php_serialize处理器是直接对所有数据进行序列化,然后得到序列化过后的数组。PHP处理器用‘ | ’肯定可以绕,但php_serialize能不能也用‘ | ’ 绕呢?

实践出真理,我们先测试一下!

<?php
highlight_file(__FILE__);
ini_set('session.serialize_handler','php_serialize');
error_reporting(0);
session_start();
$_SESSION["errorr0"] = $_GET['err'];

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?这是没有传参的结果。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?

如果把这段序列化数据放进去呢??

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?

被包含了,如果使用’ | ‘分隔开来呢?试试

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16?事实证明是可以的。也就说,现在的session_id一直是123,只要找到有漏洞的页面就可以直接打(切记一定要在同一页面,可以切换网站目录,但一定要在同一目录)。偷偷的把汤师傅的题目拿过来!!

<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php');
session_start();
class errorr1{
    public $err1;
    function __wakeup()
    {
        eval($this->err1);
    }
}

?watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXJyb3JyMA==,size_20,color_FFFFFF,t_70,g_se,x_16

?

可以看到,我们什么都没做,就打开了这个页面就自动注入了。?

?

参考PHP反序列化与Session - sijidou - 博客园


反序列化篇之Session反序列化 | Arsene.Tang

session是什么?_ImpulsionAndpower的博客-CSDN博客_session是什么意思

?

相关标签:

免责声明

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱290110527@qq.com删除。

其他信息

其他资源

Top