[代码审计]PHP中session的存储方式(WP)
Posted Y4tacker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[代码审计]PHP中session的存储方式(WP)相关的知识,希望对你有一定的参考价值。
前言:引用了各路大佬参考资料,整合成自己能够看懂并接受的笔记,欢迎指正,前面先总结Session的常用知识,后面展开对题目WP的讲解
文章目录
SESSION的常用知识
基本概念
要点
-
保存在服务器端
-
变量: $_SESSION
-
变量过滤器: filter_input(INPUT_SESSION, key)
-
设置使用专用函数: setcookie(名称, 值, 过期时间)
-
生效需要分二步完成: 先下达指令到浏览器,再由浏览器完成 cookie 写入
Session基本介绍
由于Http是一种无状态的的协议,只负责请求服务器,当它在服务器相应之后,就与浏览器失去了联系。不能保存用户的个人信息,就像一个商场和一个自动售货机或者普通的人之间的关系,所以为了弥补这个缺点Session才应声而出
Session工作原理
-
1>当一个session第一次被启用时,一个唯一的标识被存储于本地的cookie中。
-
2>首先使用session_start()函数,php从session仓库中加载已经存储的session变量。
-
3>当执行PHP脚本时,通过使用session_register()函数注册session变量。
-
4>当PHP脚本执行结束时,未被销毁的session变量会被自动保存在本地一定路径下的session库中,这个路径可以通过php.ini文件中的session.save_path指定,下次浏览网页时可以加载使用。
一些与解题相关基本概念
session存储的方式
-
file - 将 Session 保存在 文件 中。
-
cookie - Session 保存在安全加密的 Cookie 中。
-
database - Session 保存在关系型数据库中。
-
memcached / redis - Sessions 保存在其中一个快速且基于缓存的存储系统中。
-
array - Sessions 保存在 PHP 数组中,不会被持久化。
session存储格式(序列化)
php_binary暂时不知道用处,以后知道了补充,或者评论区大神给我说说
php_serialize | 经过serialize()函数序列化数组 |
---|---|
php | 键名+竖线+经过serialize()函数处理的值 |
php_binary | 键名的长度对应的ascii字符+键名+serialize()函数序列化的值 |
序列化 (Serialization)就是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
$_SESSION[“user”]=”hgg”
$_SESSION[“pwd”]=”aaaa”
序列话后成为一个字符串
user|s:6:"张三";pwd|s:8:"zhangsan";
用|
分别将键值对隔离
session如何将session存入数据库并使用
首先在mysql数据库创建存储SESSION的表:
表名为t_session
表结构为
说明:
session_key
:是用来存会话ID的
session_data
:是用来存经序列化后的$_SESSION[]里的值;
session_time
:是用来存时间戳的,这个时间戳指的是当前session在创建时的 time()+session的有效期。需要注意的是这 里的session_time的类型是int,这样可以在操作数据库时,进行大小比较!
session的存储位置
session的存储位置:一般是存储在/tmp
下,当然自己本机的位置可以自己在设置当中进行查看,查看session.save_path
session存储的默认文件名
sess_PHPSESSID:其中PHPSESSID为当前用户的sessionid值
PHP Session 基本函数的介绍
具体使用课查看参考文献[2]中基本函数介绍与使用案例
session_create_id
:创建新会话id
session_destroy
:销毁一个会话中的全部数据
session_id
:获取/设置当前会话 ID
session_name
:读取/设置会话名称
session_start
:启动新会话或者重用现有会话
session_status
:返回当前会话状态
session_unset
:释放所有的会话变量
本题的WP部分
首先打开题目对主页代码审计
大概意思是接收两个参数,一个name
与content
,之后将content
中的内容保存到’/tmp/name’文件中,很容易猜测得到这个文件一定是session.save_path
所对应的目录,那么我们很容易便可以知道我们的name
参数应该就是sess_PHPSESSID
的文件,content
中存入的就是序列化对象;
再看这句话,content
默认再参数前面拼接了"---mylocalnote---\\n
,在文件当中他肯定也会被当作序列化的键值对处理,因此我们需要将它的键key
补齐;
因此我们最终可以构造payload
content=|HGGLHA;username|s:5:"admin";&name=sess_PHPSESSID
,其中这个sess_PHPSESSID
为你本地保存的PHSESSID
值,下面教大家如何查看
因此最终payload得到了
content=|N;username|s:5:"admin";&name=sess_4f0q69vckqmtqd46sstnr2uohu
最终得到了admin的权限,再访问/flag.php
,得到flag的回显
参考文献
[1]PHP会话机制—session的基本使用
[2]php session 会话(专题)
[3]PHP Sessions
[4]PHP中如何将session存入数据库并使用
[5]PHP SESSION机制,从存储到读取
[6]彻底理解PHP的SESSION机制
[7]Predefined Constants
以上是关于[代码审计]PHP中session的存储方式(WP)的主要内容,如果未能解决你的问题,请参考以下文章