浅析session反序列化
参考自先知社区:带你走进PHP session反序列化漏洞
PHP中session的工作机制
会话的工作流程很简单,当开始一个会话时,PHP 会尝试从请求中查找会话 ID (通常通过会话 cookie),如果发现请求的Cookies、Get、Post中不存在session id,PHP 就会自动调用php_session_create_id函数创建一个新的会话,并且在http response中通过set-cookie头部发送给客户端保存.
有时候浏览器用户设置会禁止 cookie
,当在客户端cookie
被禁用的情况下,php也可以自动将session id
添加到url参数中以及form
的hidden
字段中,但这需要将php.ini
中的session.use_trans_sid
设为开启,也可以在运行时调用ini_set
来设置这个配置项。
会话开始之后,PHP 就会将会话中的数据设置到 $_SESSION
变量中,如下述代码就是一个在 $_SESSION
变量中注册变量的例子:
1 |
|
当 PHP 停止的时候,它会自动读取 $_SESSION
中的内容,并将其进行序列化
, 然后发送给会话保存管理器来进行保存。
默认情况下,PHP 使用内置的文件会话保存管理器来完成session
的保存,也可以通过配置项 session.save_handler
来修改所要采用的会话保存管理器。 对于文件会话保存管理器,会将会话数据保存到配置项session.save_path
所指定的位置。
PHP session的存取机制
php中的session
中的内容并不是放在内存中的,而是以文件的方式来存储的,存储方式就是由配置项session.save_handler
来进行确定的,默认是以文件的方式存储。
存储的文件是以sess_sessionid
来进行命名的
处理器名称 | 存储格式 |
---|---|
php | 键名 + 竖线 + 经过serialize() 函数序列化处理的值 |
php_binary | 键名的长度对应的 ASCII 字符 + 键名 + 经过serialize() 函数序列化处理的值 |
php_serialize | 经过serialize()函数序列化处理的数组 |
1 | $_SESSION['name'] = "test"; |
利用演示
1.php
1 |
|
2.php
1 |
|
首先获取序列化内容
1 | O:8:"backdoor":1:{s:4:"name";s:10:"phpinfo();";} |
然后访问1.php
1 | 1.php?a=|O:8:"backdoor":1:{s:4:"name";s:10:"phpinfo();";} |
session文件中存储内容如下
1 | a:1:{s:4:"name";s:49:"|O:8:"backdoor":1:{s:4:"name";s:10:"phpinfo();";}";} |
可以预见到的是,在2.php中 |
左侧内容会被当成键名执行,右侧内容会被当做需要序列化的内容
直接访问2.php 执行phpinfo()成功